Lücken füllen
am 20.03.2006 14:51:11 von Oliver Benning
Hallo,
ich habe zwar einen Primärschlüssel mit autoincrement-option, aber
verwende extern für die Benutzer noch einen weiteren Schlüssel, der sehr
begrenzt ist (um ihn sich besser merken zu können und um ihn in einem
Lochkartensystem erfassen zu können).
Das Problem ist, daß ich beim Vergeben neuer Nummern nicht einfach um 1
inkrementieren kann, weil schnell die Obergrenze erreicht wird und in
dem Schlüssel auch die Buchstaben A-F vorkommen. Die Datensätze
verlieren allerdings schnell genug ihre Gültigkeit, so dass immer
ausreichend Lücken vorhanden sind.
Die Frage, wie kann ich ohne großes Selektieren die nächste freie Lücke
rausfinden? Bei einer Schlüsseltabelle wäre das Problem, daß die
ungültigen Datensätze nicht gelöscht werden, sondern nur anhand des
Datums bei den SELECTs "rausfliegen". Sonst könnte ich beim Löschen auch
die Schlüssel wieder freigeben.
Gruß,
Oliver
Re: Lücken füllen
am 20.03.2006 15:23:30 von Johannes Vogel
Hi Oliver
Oliver Benning wrote:
> ich habe zwar einen Primärschlüssel mit autoincrement-option, aber
> verwende extern für die Benutzer noch einen weiteren Schlüssel, der sehr
> begrenzt ist (um ihn sich besser merken zu können und um ihn in einem
> Lochkartensystem erfassen zu können).
> Das Problem ist, daß ich beim Vergeben neuer Nummern nicht einfach um 1
> inkrementieren kann, weil schnell die Obergrenze erreicht wird und in
> dem Schlüssel auch die Buchstaben A-F vorkommen. Die Datensätze
> verlieren allerdings schnell genug ihre Gültigkeit, so dass immer
> ausreichend Lücken vorhanden sind.
> Die Frage, wie kann ich ohne großes Selektieren die nächste freie Lücke
> rausfinden? Bei einer Schlüsseltabelle wäre das Problem, daß die
> ungültigen Datensätze nicht gelöscht werden, sondern nur anhand des
> Datums bei den SELECTs "rausfliegen". Sonst könnte ich beim Löschen auch
> die Schlüssel wieder freigeben.
Ich habe mir mal für ein System die Uhrzeit in einen Code umgewandelt
und einen Zufallscode dazugehängt.
Jahr: 2001 = A, 2002 = B, ...
Monat: Jan = A, Feb = B
Monatstag: 1. = 1, 10. = A, ..
Stunde: 0 = A, 23 = ...
Minute: 0 = A, 3 = B, ...
Und dann noch eine 3-stelligen Zufallszahl angehängt.
Das ergibt dann sowas wie GCKPHQRS für jetzt. 8-stellig lässt sich noch
merken und man kommt nicht sofort drauf, dass das abhängig von der Zeit
ist. Umgekehrt lassen sich wichtige Infos wieder aus dem Code lesen.
Schön daran ist, dass er lückenlos funktioniert. Unschön ist, dass er im
2027 Probleme kriegt. Lücken suchen ist für die Katz.
HTH, Johannes
Re: Lücken füllen
am 20.03.2006 15:39:34 von Christian Kirsch
Johannes Vogel schrieb:
>> ich habe zwar einen Primärschlüssel mit autoincrement-option, aber
>> verwende extern für die Benutzer noch einen weiteren Schlüssel, der sehr
>> begrenzt ist (um ihn sich besser merken zu können und um ihn in einem
### um ihn sich besser merken zu können ###
>> Lochkartensystem erfassen zu können).
....
> Das ergibt dann sowas wie GCKPHQRS für jetzt.
Ich verstehe schon den Gedanken des OP nicht ganz (beliebige
Zeichenkombinationen ohne semantische Bedeutung sind in der Regel eben
gerade *nicht* leicht zu merken). GCKPHQRS halte ich für ein
ausgezeichnetes Beispiel - kurz und knackig und passt auf jede
Lochkarte. Aber 'leicht zu merken'? Vielleicht ist diese Bedingung ja
verzichtbar, dann täte es doch u.U. auch ein Hash über die Felder?
Re: Lücken füllen
am 20.03.2006 18:57:46 von steinboeck
Oliver Benning schrieb:
> ich habe zwar einen Primärschlüssel mit autoincrement-option, aber
> verwende extern für die Benutzer noch einen weiteren Schlüssel, der sehr
> begrenzt ist (um ihn sich besser merken zu können und um ihn in einem
> Lochkartensystem erfassen zu können).
....
Bei meinem Kunden werden Plomben verwendet, die auf die zu reinigenden
Stücke aufgezwickt werden, einen Prozess durchlaufen und dann wieder in
eine Schachtel für die nächste Verwendung kommen. Die Plomben markieren
einen Artikel während des Prozesses.
Ist das vergleichbar?
Meine Lösung ist eine Tabelle mit allen verfügbaren Plomben. Und ein
left join auf die "Bewegungen", die eine Plombe haben und noch "in
Bearbeitung" sind. Der erste Datensatz ohne passenden Bewegungssatz
(bewegung_id is null) ist der Freie.
Michael
Re: Lücken füllen
am 21.03.2006 01:12:16 von Johannes Vogel
Hi Christian
Christian Kirsch wrote:
> Johannes Vogel schrieb:
>> Das ergibt dann sowas wie GCKPHQRS für jetzt.
> Ich verstehe schon den Gedanken des OP nicht ganz (beliebige
> Zeichenkombinationen ohne semantische Bedeutung sind in der Regel eben
> gerade *nicht* leicht zu merken). GCKPHQRS halte ich für ein
> ausgezeichnetes Beispiel - kurz und knackig und passt auf jede
> Lochkarte. Aber 'leicht zu merken'? Vielleicht ist diese Bedingung ja
> verzichtbar, dann täte es doch u.U. auch ein Hash über die Felder?
MD5? 32 Zeichen? Wow, nettes Gedächnis hast du da. Kann ich davon ein
Stück bekommen? :-)
Ja, hast schon recht. Aber merkbar ist ein ziemlich weiter Begriff.
Naja, eigentlich hat er sein System bereits und möchte ja Lücken füllen.
So ist das in den NG - da wird einem selten die Antwort gegeben, die man
eigentlich lesen möchte.
Lücken füllen kann man ja mit SQL eigentlich nicht. Das einfachste wäre
wohl, einfach alle Schlüssel zu saugen und seiten Applikation die Lücke
zu suchen.
HTH, Johannes
Re: Lücken füllen
am 21.03.2006 07:10:29 von Thomas Rachel
Johannes Vogel wrote:
> Lücken füllen kann man ja mit SQL eigentlich nicht.
Geht schon.
Ich hab mir da gestern mal ein SQL-Skript zusammengestellt, das es doch
beherrscht.
Grundgedanke war, Lücken in IDs zu schlieÃen (absolut unnötig, rein
kosmetische MaÃnahme):
-- Liste fortlaufender IDs erstellen
create temporary table alle (id int auto_increment primary key, alt int);
insert into alle (alt) select NULL from files;
-- Maximum:
select @cnt:=count(*) from files;
-- delete from alle where id > @cnt; -- redundant
-- existierende löschen
update alle join files using (id) set alt=alle.id;
delete from alle where id=alt;
-- -> alle: Liste der freien IDs. (alle <= @cnt) Jetzt mit lfd versehen
alter table alle
drop column alt,
drop primary key,
modify id int,
auto_increment=0,
add column lfd int auto_increment primary key;
-- alle2: die höchsten vergebenen (nur die > @cnt)
create temporary table alle2 (lfd int auto_increment primary key, id
int);
insert into alle2 (id) select id from files where id>@cnt order by id
desc;
-- alle und alle2 verknüpfen -> höchste Nrn in die Lücken "stopfen"
-- limit ... kann man auch weglassen, dann geht alles auf einmal
create temporary table map select alle.id as neu,alle2.id as alt from
alle join alle2 using (lfd) where alle.id
limit 100
;
drop table alle;
drop table alle2;
select * from map;
-- ummappen
update files join map on id=alt set id=neu;
update sums join map on id=alt set id=neu;
update speicherorte join map on id=alt set id=neu;
update extern join map on id=alt set id=neu;
alter table files auto_increment=0;
HTH,
Thomas
--
"Macht's gut und danke für den Fisch"
Signatur zum Gedenken an Douglas Adams (1952 - 11.05.2001)
http://www.douglasadams.com/
Re: Lücken füllen
am 21.03.2006 11:55:35 von Johannes Vogel
Hi Thomas
Thomas Rachel wrote:
> Johannes Vogel wrote:
>> Lücken füllen kann man ja mit SQL eigentlich nicht.
Vielleicht etwas plakativ ausgedrückt. Gemeint ist, dass man nicht
selektieren kann, was nicht existiert.
> Geht schon.
Nein. (im obigen Sinne)
> Ich hab mir da gestern mal ein SQL-Skript zusammengestellt, das es doch
> beherrscht.
> Grundgedanke war, Lücken in IDs zu schlieÃen (absolut unnötig, rein
> kosmetische MaÃnahme):
> -- Liste fortlaufender IDs erstellen
> create temporary table alle (id int auto_increment primary key, alt int);
> insert into alle (alt) select NULL from files;
Hier generierst du Inhalt. Aus dieser Datenbasis selektierst du später.
> -- Maximum:
....[Furchtbar komplizierter SQL-Code]...
> alter table files auto_increment=0;
Ãbrigens hat der OP ja keine Integer-Werte, sondern benutzt auch
alphanumerische Zeichen. Damit fallen auto_increment-Attribute raus.
Grüess, Johannes
Re: Lücken füllen
am 21.03.2006 13:04:59 von Thomas Rachel
Johannes Vogel wrote:
> Hier generierst du Inhalt. Aus dieser Datenbasis selektierst du später.
Ja, ok - ist natürlich auf indirektem Wege.
Aber ohne Zuhilfenahme externen Codes...
> Ãbrigens hat der OP ja keine Integer-Werte, sondern benutzt auch
> alphanumerische Zeichen. Damit fallen auto_increment-Attribute raus.
Hm, stimmt. Aber auch da sollte es - je nach Kompliziertheit der Codes -
funktionieren, wenn man Tabellen mit den Inhalten A..Z und 0..9 (je nach
gewünschter Inhaltskombination) miteinander kombiniert.
Locking wäre vielleicht nicht schlecht - das hab ich bei mir jetzt mal
bleiben lassen...
Thomas