Newsscript: MySql Index-Spalte manuell neu sortieren?
Fritz
- datenbank
Hallo,
ich hab ein "Logik-Problem":
In einem Newsscript (PHP / MySql) kann ich im Admin-Bereich Einträge auswählen, und die gewählten Einträge löschen und editieren.
Die Einträge werden in der Anzeige per $sql = "SELECT ... FROM ...ORDER BY id DESC ... automatisch angeordnet, neuester Eintrag oben. (Feld id ist auf autoincrement gesetzt)
Nun möchte ich per Adminbereich einzelne Einträge manuell sortieren, z.B. einen älteren Eintrag weiter nach oben setzen. Dazu muß ich das Feld id editieren. Kein Problem. Aber wie kann ich _sicherstellen_, dass bei diesem manuellen Editieren keine bereits existierende id eingegeben wird?
Hat jemand einen Tipp? Oder gibt's vielleicht sogar in MySql so was?
Gruß Fritz
Hi,
Nun möchte ich per Adminbereich einzelne Einträge manuell sortieren, z.B. einen älteren Eintrag weiter nach oben setzen. Dazu muß ich das Feld id editieren. Kein Problem. Aber wie kann ich _sicherstellen_, dass bei diesem manuellen Editieren keine bereits existierende id eingegeben wird?
ganz einfach: Benutze hierfür eine Spalte, die *nicht* der Identifikation des Datensatzes dient, denn eine solche Spalte dient *nur* der Identifikation des Datensatzes.
Cheatah
Hallo!
Nun möchte ich per Adminbereich einzelne Einträge manuell sortieren, z.B. einen älteren Eintrag weiter nach oben setzen. Dazu muß ich das Feld id editieren. Kein Problem. Aber wie kann ich _sicherstellen_, dass bei diesem manuellen Editieren keine bereits existierende id eingegeben wird?
Lasse die Finger von die ID. Die ID sollte nicht zum manuellen sortieren verwendet werden. Damit nimmst Du ihr auch ihre Aufgabe.
Lege eine weiter Spalte an, in der DDu die Sortierreihenfolge fest legst. Anhand dieser Spalte kannst Du nun die Reihenfolge bestimmen.
Hat jemand einen Tipp? Oder gibt's vielleicht sogar in MySql so was?
Nein, gibt es nicht!
MfG, André Laugks
Hi,
Die Einträge werden in der Anzeige per $sql = "SELECT ... FROM ...ORDER BY id DESC ... automatisch angeordnet, neuester Eintrag oben. (Feld id ist auf autoincrement gesetzt)
Nun möchte ich per Adminbereich einzelne Einträge manuell sortieren, z.B. einen älteren Eintrag weiter nach oben setzen. Dazu muß ich das Feld id editieren. Kein Problem. Aber wie kann ich _sicherstellen_, dass bei diesem manuellen Editieren keine bereits existierende id eingegeben wird?
Eine id-Spalte dient zum Identifieren von Datensätzen und zu sonst nichts.
Insbesondere sind nachträgliche Änderungen der id zu unterlassen - dies würde z.B. Verknüpfungen mit anderen Tabellen zerstören.
Benutze eine Spalte, die NICHT die id-Spalte ist, für die Angabe einer Sortierreihenfolge.
Definiere auch für diese Spalte einen Index, und zwar einen UNIQUE INDEX.
Dann klopft Dir MySQL auf die Finger, wenn Du einen Wert doppelt vergeben willst.
cu,
Andreas
Hallo,
Die Einträge werden in der Anzeige per $sql = "SELECT ... FROM ...ORDER BY id DESC ... automatisch angeordnet, neuester Eintrag oben. (Feld id ist auf autoincrement gesetzt)
Nun möchte ich per Adminbereich einzelne Einträge manuell sortieren, z.B. einen älteren Eintrag weiter nach oben setzen. Dazu muß ich das Feld id editieren. Kein Problem. Aber wie kann ich _sicherstellen_, dass bei diesem manuellen Editieren keine bereits existierende id eingegeben wird?Eine id-Spalte dient zum Identifieren von Datensätzen und zu sonst nichts.
Insbesondere sind nachträgliche Änderungen der id zu unterlassen - dies würde z.B. Verknüpfungen mit anderen Tabellen zerstören.
wer sagt denn, dass ich die Verknüpfung anhand der Spalte id durchführe?
und wer sagt, dass ich die fragliche Tabelle überhaupt verknüpft habe?
Ersetze in meiner Frage "id" durch einen anderen Namen, z.B. "sort".
Aber dann stellen sich andere Fragen:
Gruß Fritz
Hallo!
wer sagt denn, dass ich die Verknüpfung anhand der Spalte id durchführe?
und wer sagt, dass ich die fragliche Tabelle überhaupt verknüpft habe?
Ersetze in meiner Frage "id" durch einen anderen Namen, z.B. "sort".
Wenn die Spalte id mit keiner anderen Tabelle verknüpft ist, kannst Du die id ändern.
Nur hast Du dann nicht den Sinn der Spalte "id" verstanden, die die Eigenschaft AUTO_INCREMENT besitzt.
Du hast doch sicherlich eine Liste aller Beiträge. Über die Liste kommt man sicherlich an den gesamten Beitrag. Dazu benötigst Du die id des Beitrages. Was ist nun, wenn Du die id änderst und ein User hat sich aber ein Bookmark auf diesen Beitrag gesetzt.
Aber dann stellen sich andere Fragen:
- Muss es zwangsläufig in jeder Tabelle eine Spalte "id UNIQUE autoincrement" geben?
Nein, sollte aber.
- Wenn ja: eine zweite Spalte mit autoincrement ist nicht zulässig - d.h. entweder ich kann die "id" automatisch durchnummerieren, oder die "sort".
In MySQL ist das nicht möglich. Macht auch Sinn.
Es wird doch wohl kein Problem sein, die höchste Sortiernummer raus zu finden. Für den neuesten Datensatz nimmst Du die plus 1.
MfG, André Laugks
Hallo,
Was ist nun, wenn Du die id änderst und ein User hat sich aber ein Bookmark auf diesen Beitrag gesetzt.
Danke, das war der entscheidende Hinweis.
Gruß Fritz
Hello,
das bribgt mich noch eine andedre Frage:
Wenn man eine "Sortierrang-Spalte" hat, und will Beiträge umsorieren, dann kommt es ja vor, dass der Zielrang bereits belegt ist, also keine Lücke im Nummernkreis vorhanden ist.
12 36789ACF K
^ |
+---------+
Also der Satz K soll nun beispielsweise VOR dem Rang 3 einsortiert werden.
(Die Buchstaben habe ich hier nur wegen der besseren Lesbarkeit, der Rang ist in der Tabelle eine rein numerische Größe!)
Nun müsste ich zuvor ja ein Update-Query durchführen:
Update $table set rang = rang +1 where rang <= 3 and $sonstigeFilter;
Ist das mit allen gängigen SQL-DBMS so zulässig? Schließlich wird die Indizierte Spalte selber geändert. Bei Desktopdatenbanken konnten solche "Selbstbezugabfragen" zu verheerenden Folgen führen.
12 4789ABDG L
^ |
+---------+
Dann müsste die Tabelle hinterher so aussehen.
Wahrscheinlich müsste man auch bei SQL die Tabelle für eine Vertikalmanipulation sperren, oder werden die Queries ausreichend serialisiert? Der ganze Vorgang besteht ja aus drei Teilen:
Erst danach dürften andere Queries wieder in der Tabelle rumfummeln.
Die obige Betrachtung ist mir noch einigemaßen flüssig aus der Tastatur gequollen, aber wie sieht es nun aus, wenn man aus der rangfolge einen Satz löscht:
1236789ACF K
|
v
danach sieht die Rangfolgespalte dann so aus:
12 6789ACF K
Im Prinzip wäre sie für die rechnerische Bearbeitung vielleicht schon kaputt so. Vielleicht dürfte man gar keine Lücken entstehen lassen. Wie könnte man aber diese Lücken nun wieder schließen, also die Datensätze aus dem Filterbereich wieder Lückenlos von 1 bis n durchnumerieren, ohne ihre aktuelle Rangfolge zu zerstören. Das ganze natürlich mit minimaler Anzahl von Queries. Es könnten in der Praxis schon mal 250 Datensätze in einem Filterbreich werden.
Um es praktich zu hinterlegen:
Ich habe Angebote zu verschiedenen Kategorien. Die werden innerhalb ihrer Kategorie immer nach einer subjektiven Rangfolge sortiert. Es kpmmt häfiger vor, dass ein Angebot aus einer Kategorie in eine andere verschoben wird.
( Das ganze Spielchen war bei bTrieve kein Problem, da die Datenhaltung dort tabellenintern mit einer verketten Liste stattfindet und man nur Vorgänger und Nachfolger miteinander verknüpfen musste. Problem ist da dann das Duplicatemanagement. )
Also nochmal die Frage:
Wie würdet Ihr eine SQL-Statementgruppe aufbauen, um eine Datensatzgruppe durchzunumerieren? Funktionieren die SQL-User-Variablen in der 4er Version von MySQL?
Liebe Grüße aus http://www.braunschweig.de
Tom