anpera.net https://anpera.dyndns.org/phpbb3/ |
|
Fortlaufende ID / Häuser https://anpera.dyndns.org/phpbb3/viewtopic.php?f=34&t=4622 |
Seite 1 von 1 |
Autor: | vernisage [ Do 31 Jul, 2008 19:34 ] |
Betreff des Beitrags: | Fortlaufende ID / Häuser |
Hallo, grüße Euch. Ich wollte mal fragen, wie ich es machen kann, dass nach dem Löschen eines Hauses (ob nun durch die DB oder durch den Hausmeister) die bereits vergebene ID wieder verwendet wird. Praktisch so: Ich lösche Haus mit der ID 90. User XY baut sich ein Haus und bekommt die Hausnummer 91. Nun besteht eine Lücke in den Hausnummern Haus Nr 89 ist bewohnt Haus Nr 90 gibt es nicht Haus Nr 91 wird gebaut. Und dann noch eine Frage. Ist es eigentlich riskant, oder kann es zu arge Probs kommen, wenn ich über den Hausmeister überhaupt Häuser, die leer stehen (Verkauf, Bauruinen), lösche und im Anschluss daran alle noch vorhandenen Häuser ID-technisch bearbeite? Damit keine solchen großen Lücken von Haus zu Haus entstehen? Sieht einfach nicht gut aus, wenn Haus Nr 3 neben Haus Nr 12 steht. Ich muss doch dazu wirklich auch alle Schlüssel bearbeiten, oder? Geht das alles einfach so? Und wie bekomme ich das ID-Problem gelöst? Danke und Grüße, verni ![]() |
Autor: | Kevz [ Do 31 Jul, 2008 20:21 ] |
Betreff des Beitrags: | Re: Fortlaufende ID / Häuser |
Wie wäre es, wenn Du einfach ne Variable (typ integer) auf 0 setzt und in der Schleife, wo die Häuser aufgelistet werden, diese um jeweils +1 erhöhst?! So erhälst Du die eine Reihenfolge, die von den Zahlen stimmt und musst keine Änderungen an der Datenbank vornehmen... |
Autor: | Eliwood [ Fr 01 Aug, 2008 12:33 ] |
Betreff des Beitrags: | Re: Fortlaufende ID / Häuser |
Die ID soll das sein, was sie ist - einzigartig. Da irgend etwas zu ändern ist nicht anzuraten. Du kannst aber ein neues Feld erstellen, sagen housenumber in der Haustabelle. Für das Vergeben einer neuen Hausnummer prüfst du dann, ob die höchste Hausnummer in der Tabelle gleich der Summe Häuser ist. Wenn ja, hat es keine Lücken, wenn nein, gibt es Lücken. Die Lücken kannst du mit einer for-Schleife füllen (zur Zeit fällt mir kein besserer Algo ein): $this->bbcode_second_pass_code('', '$res = db_query("SELECT MAX(h.housenumber), COUNT(h.houseid) AS 'counter' FROM houses h"); $row = db_fetch_assoc($res); if($row['housenumber'] == $row['counter']) { # Keine Lücken, neue Hausnummer = housenumbers+1 $newHouseNumber = ++$row['housenumber']; } else { # Lücken vorhanden $res = db_query('SELECT h.housenumber FROM houses h ORDER BY h.housenumber ASC'); $i = 1; while($row = db_fetch_assoc($res)) { # Solange Hausnummer - 1 0 ist, sind keine Lücken vorhanden # Die Lücke wird entdeckt, sobald die Anzahl Schleifendurchläufe nicht mehr der aktuellen Hausnummer entspricht $diff = $row['housenumber'] - $i; if($diff !== 0) { $newHouseNumber = $i; # $i muss die Hausnummer sein, die es nicht gibt. break; # Schleifenabbruch } } }') So ungefähr müsste es funktionieren. Die Voraussetzung ist allerdings, dass die erste Hausnummer 1 ist, und nicht 0! Ebenso kann nicht davon ausgegangen werden, dass der Code funktioniert, er soll eher als Idee dienen denn als Codeschnipsel. |
Autor: | vernisage [ Fr 01 Aug, 2008 14:58 ] |
Betreff des Beitrags: | Re: Fortlaufende ID / Häuser |
Oha. Das muss ich mal probieren und herausfinden, wo ich das mit einsetze. Ist erstmal schon eine gute Hilfe, Eli. Ich danke dir. |
Autor: | Auric [ So 03 Aug, 2008 18:35 ] |
Betreff des Beitrags: | Re: Fortlaufende ID / Häuser |
Ist bei mir seid 0.80 oder so implementiert, in der neuen Version im Subversion sogar mit Unterstützung für die einzelnen Straßen (wird dann ein bisschen komplexer). Prinzipiell kann man Lücken in Tabellen recht komfortabel über Joins auf die selbe Tabelle von MySQL ausfindig machen, Eliwoods Vareiante wird ein bisschen arg Rechen- und vor allem Speicherintensiv, wenn man erstmal veiel Häuser drin hat, da ja immer alle Nummern aus der DB geholt werden, was mal gerne in die tausende gehen kann. |
Autor: | vernisage [ Mo 04 Aug, 2008 16:56 ] |
Betreff des Beitrags: | Re: Fortlaufende ID / Häuser |
Ich war mal so frei und habe in deine source geschaut, Auric, und wie ich gesehen habe, haben wir beide annähernd das gleiche Hausscript (ich jedoch nicht die Ausbaustufen). Wo genau bitte sitzt das bei dir? |
Autor: | Eliwood [ Mo 04 Aug, 2008 17:16 ] |
Betreff des Beitrags: | Re: Fortlaufende ID / Häuser |
Auric hat geschrieben: Prinzipiell kann man Lücken in Tabellen recht komfortabel über Joins auf die selbe Tabelle von MySQL ausfindig machen, Eliwoods Vareiante wird ein bisschen arg Rechen- und vor allem Speicherintensiv, wenn man erstmal veiel Häuser drin hat, da ja immer alle Nummern aus der DB geholt werden, was mal gerne in die tausende gehen kann. Naja, ich bin davon Ausgegangen, dass es nicht soooo viele Häuser sein können. Vor allem, wenn die NUmmern ständig nachgefüllt werden. Die beste Lösung wäre wohl eine zweite Tabelle mit Hausnummer (Oder Hausnummer|Strasse) => used/unused. Aber die Variante mit Join musst du mir mal verraten Oo |
Autor: | Auric [ Di 05 Aug, 2008 18:05 ] |
Betreff des Beitrags: | Re: Fortlaufende ID / Häuser |
Da ich gerade in bisschen Zeit habe will ich mal schauen ob ich meine Ergüsse von früher noch wieder zusammen bekomme... Der eigentliche Trick ist ein Join auf die gleiche tabelle, wobei man als zweiten Datensatz immer den jeweils nächsten in der Liste nimmt. $this->bbcode_second_pass_code('', 'SELECT a.houseid, b.houseid FROM houses a LEFT JOIN houses b ON b.houseid = a.houseid +1') Das Spuckt uns an allen Stellen, wo eine Lücke herrscht ein NULL auf der rechten Seite aus, ebenso bei den letzen eintrag, der ja keinen Nachfolger mehr haben kann. Was nun noch zu tun bleibt ist die geringste id ohne Nachfolger ausfindig zu machen. Mit Hilfe von MIN und ISNULL kein Problem: $this->bbcode_second_pass_code('', 'SELECT MIN(a.houseid) +1 AS newid FROM houses a LEFT JOIN houses b ON b.houseid = a.houseid +1 WHERE ISNULL(b.houseid)') Tja, das sollte es eigentlich auch schon gewesen sein... aber es gibt noch 1-2 Sonderfälle, die man Berücksichtigen muss: 1.) Fehlt das erste Haus, so wird nie nummer 1 sondern immer die nächste passende Stele zurück gegeben. 2.) Ist Die Tabelle leer, so wird NULL zurück gegeben Das kann man entweder vorher über separate Querys abfangen, ignorieren (bei 1.), denn das ist meist das haus des Admins ;-) oder aber man baut einen etwas komplexeren Query, der dann als eierlegende Wollmilchsau fungiert: $this->bbcode_second_pass_code('', ' SELECT IF( (SELECT MIN(`houseid`) FROM `houses`) > 1, 1, ( SELECT IF( ISNULL(MIN(`h`.`houseid`)+1), 1, MIN(`h`.`houseid`)+1 ) AS `neu` FROM `houses` `h` LEFT JOIN `houses` `n` ON `n`.`houseid` = `h`.`houseid`+1 WHERE ISNULL(n.houseid) ) ) AS `neu`') Im Prinzip kann man diesen Query immer, also ohne eine Prüfung ob MAX(houseid) > COUNT(houseid), verwenden, da er immer die kleinste Nummer, die nicht besetzt ist zurück gibt - dazu kann auch die nächste reguläre Zahl gehören. Wer spass dran hat nun nun auch noch Straßen einführt, die immer von unten aufgefüllt werden solen, der kann sich die folgende funktion mal anschauen, die bei mir den obrigen Query zusammen baut: $this->bbcode_second_pass_code('', 'define('HAUS_NR_FIELD','hausnr'); define('HAUS_ID_FIELD','houseid'); define('HAUS_TABLE','houses'); function generate_id($street_id = false) { $loc_str = $street_id !== false ? 'WHERE `street_id`="' . $street_id . '"' : ''; $loc_str2 = $street_id !== false ? 'AND `h`.`street_id`=' . $street_id : ''; $field_str = $street_id !== false ? HAUS_NR_FIELD : HAUS_ID_FIELD; $sql = 'SELECT IF((SELECT MIN(`' . $field_str . '`) FROM `' . HAUS_TABLE . '` ' . $loc_str . ')>1,1,(SELECT IF(ISNULL(MIN(`h`.`' . $field_str . '`)+1),1,MIN(`h`.`' . $field_str . '`)+1) AS `new` FROM `' . HAUS_TABLE . '` `h` LEFT OUTER JOIN `' . HAUS_TABLE . '` `n` ON `n`.`' . $field_str . '` = `h`.`' . $field_str . '`+1 WHERE ISNULL(`n`.`' . $field_str . '`) ' . $loc_str2 . ')) AS `neu`'; $res = dying_query($sql, 'Generieren eines neuen HausIndexes schlug fehl', __FILE__, __LINE__); $neu = db_fetch_assoc($res); db_free_result($res); return $neu['neu']; }') |
Autor: | Eliwood [ Di 05 Aug, 2008 18:40 ] |
Betreff des Beitrags: | Re: Fortlaufende ID / Häuser |
Ach verdammt. An so n' Trick hab ich gar nicht erst gedacht. Schande über mich. ![]() Aber danke für den Denkanstoss und den Ansatz ![]() Leider ist es mit der Methode nicht Möglich, *alle* freien Hausnummern zu bekommen... Wäre doch ein nettes Extra für ein Haussystem, wenn man sich die Hausnummern aussuchen könnte. Je niedriger, desto teurer. Oder so. :> |
Seite 1 von 1 | Alle Zeiten sind UTC + 1 Stunde |
Powered by phpBB® Forum Software © phpBB Group https://www.phpbb.com/ |