Dakuan
Anmeldungsdatum: 2. November 2004
Beiträge: 6514
Wohnort: Hamburg
|
Vorweg, ich habe mich schwer getan, einen passenden Titel zu finden, hoffe aber damit das Interesse potentieller Helfer erweckt zu haben. Die Situation ist folgende, ich bastle seit einiger Zeit an einer Notizzettel Verwaltung. Die Notizen sind dabei in einer Baumstruktur angeordnet. Bisher werden diese nur anhand des Pfades identifiziert. Wenn ich jetzt Querverbindungen zwischen den Notizen herstellen möchte, brauche ich eine eindeutige ID-Nummer, die ich bisher nicht habe. Die ID sollte auch erhalten bleiben, wenn eine Notiz im Baum verschoben wird. Eines der Probleme besteht darin, daß die Titel einer Notiz mehrfach auftreten dürfen, also z.B.
Projekte/dieses/todo
also der Titel "todo" oder "Fehler" kann durchaus mehrfach auftreten. Aber alle Notizen haben Zeitstempel (erstellt/modified). Die Zeitstempel sind aber auch nicht unbedingt zur Identifikation geeignet, da einige Dateien auch aus externen Datenquellen automatisch erzeugt werden, was bei ca. 4000 Einträgen zwischen 3 Sec und 5 Min dauert, wodurch dann etliche Stempel idendisch sind (Auflösung 1 Sec). Was ich also suche, ist eine eindeutige Identifikation der Notizen, die auch bei Verschiebung oder Veränderung des Inhalts erhalten bleibt und irgendwie auch "kollisionssicher" ist. Mein erste Gedanke dazu war "UUID". Aber wie erstellt man so etwas und kann das in meinem Fall die Lösung sein?
|
Developer92
Anmeldungsdatum: 31. Dezember 2008
Beiträge: 4101
|
Dakuan schrieb: Eines der Probleme besteht darin, daß die Titel einer Notiz mehrfach auftreten dürfen, also z.B. […]
Generell eine eher schlechte Idee, gerade weil man da auch lustige Fehler mit Sonderzeichen und ähnlichem erhalten kann.
Aber alle Notizen haben Zeitstempel (erstellt/modified). Die Zeitstempel sind aber auch nicht unbedingt zur Identifikation geeignet, […]
Zumal sich Zeitstempel auch ändern können (und auch regelmäßig tun, je nachdem wie der Datenträger auf dem man arbeitet eingehängt wurde). Es gibt ja auch nicht nur einen Zeitstempel, sondern für eine Datei beispielsweise drei verschiedene: ctime, mtime und atime. Aus Erfahrung kann ich dir sagen, dass man damit nicht arbeiten möchte, wenn man nicht muss ☺
Mein erste Gedanke dazu war "UUID".
Wäre jetzt auch mein Vorschlag gewesen.
Aber wie erstellt man so etwas und kann das in meinem Fall die Lösung sein?
Die Erstellung von UUIDs ist standardisiert, und in der Regel gibt es auch für die unterschiedlichsten Programmiersprachen bereits fertige Implementierungen, teilweise sogar in der Standardbibliothek (etwa bei Python). Wikipedia hat dazu einen netten Artikel: UUID Wie du das dann in deine bestehende Lösung integrierst ist wiederum eine andere Frage. Ich würde die UUID in die erste Zeile der Notiz schreiben, alternativ könnte man die UUID auch in den Dateinamen integrieren. Da gibt es möglicherweise aber auch noch bessere Ansätze (der Anfang der Datei könnte auch ein JSON-formatierter Block sein, in welchem man später etwa noch mehr Daten unterbringen könnte. Aber dazu müsste man jetzt natürlich wissen, wie dein bisheriges System aussieht).
|
Dakuan
(Themenstarter)
Anmeldungsdatum: 2. November 2004
Beiträge: 6514
Wohnort: Hamburg
|
Generell eine eher schlechte Idee, gerade weil man da auch lustige Fehler mit Sonderzeichen und ähnlichem erhalten kann.
Sonderzeichen sollten kein Problem sein, da alle Texte durchgängig UTF-8 Kodieert sind.
Zumal sich Zeitstempel auch ändern können ...
Ich benute eigene Zeitstempel, die nichts mit dem Dateisystem zu tun haben. Der Erstellungszeitstempel ist im Datensatz kodiert und ändert sich, im Gegensatz zum "modified" Zeitstempel nicht mehr. Aber da bei automatisierter Dateierzeugung viele Dateien innerhalb einer Sekunde erzeugt werden können, ist er nicht wirklich eindeutig.
Mein erste Gedanke dazu war "UUID".
Wäre jetzt auch mein Vorschlag gewesen.
gut Wikipedia hat dazu einen netten Artikel: UUID
Ok, den muss ich mir jetzt mal in Ruhr reinziehen.
Wie du das dann in deine bestehende Lösung integrierst ist wiederum eine andere Frage. Ich würde die UUID in die erste Zeile der Notiz schreiben, ...
Das wiederum sollte kein Problem sein, da ich, entgegen der allgemein gewünschten Vorgaben, ein binäres Dateiformat verwende und die Dateiversion Teil des Formats ist.
Aber dazu müsste man jetzt natürlich wissen, wie dein bisheriges System aussieht).
Alle Notizen befinden sich in einer einzigen (binär) Datei und sind in einer Baumstruktur angeordnet. Die Position im Baum ergibt sich aus der vorgeschalteten Pfad Information.
|
Developer92
Anmeldungsdatum: 31. Dezember 2008
Beiträge: 4101
|
Dakuan schrieb: Sonderzeichen sollten kein Problem sein, da alle Texte durchgängig UTF-8 Kodieert sind.
Ich bin da trotzdem immer etwas vorsichtig (zugegeben, unter Linux hatte ich da schon lange keine Probleme mehr. Unter Windows hingegen, nunja…)
Alle Notizen befinden sich in einer einzigen (binär) Datei und sind in einer Baumstruktur angeordnet. Die Position im Baum ergibt sich aus der vorgeschalteten Pfad Information.
Achso, jetzt wird das etwas klarer. Ich dachte die Dateien würden alle in entsprechenden Ordnen liegen, wie eben eine (ganz einfache) Sammlung von Notizen. Aber wenn das sowieso schon als Datenstruktur mit eigenem Format vorliegt, dann sprichst ja prinzipiell so wie ich das sehe nichts dagegen das auch noch um eine UUID zu erweitern. Und UUIDs sind da wirklich eine gute Lösung … wurden ja genau für solche Fälle entwickelt.
|
track
Anmeldungsdatum: 26. Juni 2008
Beiträge: 7174
Wohnort: Wolfen (S-A)
|
Was kennzeichnet einen bestimmten "Notizzettel" bei Dir eigentlich eindeutig ?
Ist es der genaue Speicherort auf der Festplatte ? → das wäre der Inode, der bliebe eindeutig beim Umbenennen und Verschieben der Datei, und auch wenn die Notiz aktualisiert wird. Würde sich aber ändern, sobald man ihn kopiert oder umlagert auf eine andere Partition. Ist es der genaue, wörtliche Inhalt der Notiz ? → der wäre praktisch eindeutig beschrieben durch einen Hashwert wie z.B. md5sum Aber wehe, es wird auch nur ein Punkt im Text verändert !
Das wäre also die 1. Frage: wodurch wird ein bestimmter Notizzettel eindeutig bestimmt ? LG, track Nachtrag: Ich sehe gerade, dass Du die Zettel alle in 1 Datei stehen hast. - Wie greifst Du auf sie zu ? Denn in dem Fall wäre es vermutlich das einfachste, dafür eine Datenbank zu verwenden: da hast Du in Gestalt des Primärschlüssels automatisch einen eindeutigen Index. (Der Strukturbaum wäre in dem Fall unabhängig davon, sozusagen ein sekundäres Merkmal)
|
rklm
Projektleitung
Anmeldungsdatum: 16. Oktober 2011
Beiträge: 13216
|
Wenn Du SQLite nimmst, dann kannst Du auch die automatisch generierte ROWID nehmen.
|
Dakuan
(Themenstarter)
Anmeldungsdatum: 2. November 2004
Beiträge: 6514
Wohnort: Hamburg
|
Developer92 schrieb_ Ich bin da trotzdem immer etwas vorsichtig ...
Vorsicht ist hier tatsächlich angebracht, da der Schrägstrich als Trennzeichen im Pfad auch Teil des Namens sein kann. Nicht umsonst habe ich eine Datei namens "Elchtest" 😉 Was kennzeichnet einen bestimmten "Notizzettel" bei Dir eigentlich eindeutig ?
Nur seine Position im Baum, also der Pfad. Dieser kann sich aber ändern.
Aber wehe, es wird auch nur ein Punkt im Text verändert !
Das passiert eigentlich ständig irgendwo in der Datei. Das ist ja ein Arbeitshilfsmittel.
Ich sehe gerade, dass Du die Zettel alle in 1 Datei stehen hast. - Wie greifst Du auf sie zu ?
Am Anfang wird die gesamte Datei einmal gelesen und eine interne (temporäre) Index Tabelle aufgebaut.
Denn in dem Fall wäre es vermutlich das einfachste, dafür eine Datenbank zu verwenden:
Vermutlich hast Du Recht aber ich habe keine Ahnung, wie man sowas macht. Und ich denke, das ist auch eine Frage der Datenmenge. Das mit den UUIDs gefällt mir eigentlich sehr gut. Aber so wie es aussieht muss ich um libuuid nutzen zu können das dev Paket von e2fsprogs installieren.
|
rklm
Projektleitung
Anmeldungsdatum: 16. Oktober 2011
Beiträge: 13216
|
Dakuan schrieb: Developer92 schrieb_
Denn in dem Fall wäre es vermutlich das einfachste, dafür eine Datenbank zu verwenden:
Vermutlich hast Du Recht aber ich habe keine Ahnung, wie man sowas macht. Und ich denke, das ist auch eine Frage der Datenmenge.
SQLite einbinden, Schema definieren und Code einbauen, der es anlegt. | CREATE TABLE notes (
id integer primary key,
parent_id integer references notes(id) null,
name varchar(100) not null,
text varchar not null
);
|
Beispielhafte Benutzung mit dem Kommandozeilentool sqlite3 : 1
2
3
4
5
6
7
8
9
10
11
12
13 | sqlite> pragma foreign_keys = true;
sqlite> insert into notes ( name, text ) values ( 'root', 'text bar bar' );
sqlite> select last_insert_rowid();
1
sqlite> insert into notes ( parent_id, name, text ) values ( last_insert_rowid(), 'kind 1', '111' );
sqlite> select * from notes;
1||root|text bar bar
2|1|kind 1|111
sqlite> insert into notes ( parent_id, name, text ) values ( last_insert_rowid(), 'kind 2', '222' );
sqlite> select * from notes;
1||root|text bar bar
2|1|kind 1|111
3|2|kind 2|222
|
Rekursive Abfragen gehen sogar mit SQLite: | sqlite> with recursive teilbaum(n,a,b,c) as ( select * from notes where id = 2 UNION select notes.* from notes, teilbaum where parent_id = teilbaum.n ) select * from teilbaum;
2|1|kind 1|111
3|2|kind 2|222
sqlite> with recursive teilbaum(n) as ( select 2 UNION select notes.id from notes, teilbaum where parent_id = teilbaum.n ) select * from teilbaum;
2
3
sqlite> with recursive teilbaum(n) as ( select 2 UNION select notes.id from notes, teilbaum where parent_id = teilbaum.n ) select * from notes where id in teilbaum;
2|1|kind 1|111
3|2|kind 2|222
|
☺ (Doku).
Das mit den UUIDs gefällt mir eigentlich sehr gut. Aber so wie es aussieht muss ich um libuuid nutzen zu können das dev Paket von e2fsprogs installieren.
Naja, da Du anscheinend nur immer einen Prozess hast, der auf die Datei zugreift, und sie auch nur am Stück liest oder schreibst, reicht auch eine einfache Vergabe einer Zahl als ID.
|
Dakuan
(Themenstarter)
Anmeldungsdatum: 2. November 2004
Beiträge: 6514
Wohnort: Hamburg
|
Naja, da Du anscheinend nur immer einen Prozess hast, der auf die Datei zugreift, und sie auch nur am Stück liest oder schreibst, reicht auch eine einfache Vergabe einer Zahl als ID.
Das ist richtig. Den Tabellenindex kann ich dafür allerdings nicht nehmen. Der soll ohne Lücken bleiben, damit meine Speicherplatzberechnung einfach bleibt. Allerdings könnte ich die Zahl einfach immer hoch zählen. Ich habe mal überschlagen, wann der Zähler überläuft, wenn ich 100 neue Datensätze pro Tag anlege. Aber das Ergebnis ist so astronomisch, dass ich es morgen lieber nochmal nachrechne, bevor ich mich hier wieder blamiere.
|