Tags:
create new tag
, view all tags

Style Guide für den Entwurf von Datenbanken

Entwurf Benno Luthiger, 10.4.2007

Zweck: Werden bei der Benennung von DB-Objekten gewisse Regeln vereinbart und eingehalten, so steigert dies die Verständlichkeit. Der Code dokumentiert sich selbst. Dies erleichtert die Kommunikation in Software-Projekten, in welchen mehr als eine Person involviert ist.

Allgemeine Regel: Die Namen für die Objekte sollen in englischer Sprache gehalten werden.

Objekt Regel/Syntax Beispiel Begründung
Tabelle Präfix tbl tblPerson Der Präfix zeigt an, um welche Art Objekt es sich handelt.
Index Präfix idx + Stamm des Tabellen-Namens + _NN (Nummer) idxPerson_01 Der Präfix zeigt an, um welche Art Objekt es sich handelt. Der Stamm zeigt an, welche Tabelle indiziert wird.
View Präfix view viewPerson_01 Der Präfix zeigt an, um welche Art Objekt es sich handelt. Der Stamm zeigt an, aus welcher Tabelle die View kommt.
Primärschlüssel Stamm des Tabellennnamens + ID : kein Präfix PersonID Grossbuchstabe und ID machen Schlüsselfeld sofort sichtbar. Taucht der Schlüssel in einer anderen Tabelle als Fremdschlüssel auf, so wird sofort deutlich, welche Tabelle referenziert wird.
Textfeld Präfix s sFirstname Gilt für char, varchar, text etc.
Numerisches Feld Präfix n nSection Gilt für int, float etc.
Datums-Feld Präfix dt dtCreation Gilt für date, timestamp etc.

Beispiele:

CREATE TABLE tblPerson ( 
 PersonID        int unsigned not null auto_increment, 
 sName           varchar(99) not null, 
 sFirstname      varchar(50) not null, 
 nSection        tinyint not null default 0, 
 sRemark         text, 
 dtCreation      timestamp, 
 dtMutation      timestamp, 
 PRIMARY KEY (PersonID), 
 INDEX idxPerson_01 (sName, sFirstname) 
); 
 
CREATE TABLE tblPersonRole ( 
 PersonID  int unsigned not null,  
 RoleID  int unsigned not null,  
 nType  tinyint not null default 0, 
 PRIMARY KEY (PersonID, RoleID) 
); 

Kommentar von Swen Vermeul

  1. Die vorgeschlagenen Namensgebungen für DB-Objekte setzt eine Gross-Kleinschreibung für DB-Objekte voraus. Allerdings macht Oracle traditionellerweise keinen Unterschied, was die Lesbarkeit von Objekten wie TBLPERSON sehr erschwert!
  2. Wenn schon eine Objekttypbezeichnung im Namen auftauchen soll, dann als SUFFIX, nicht als Präfix. Der Suffix sollte zusätzlich mit einem Underscore versehen sein, um ihn vom Namen abzugrenzen, Bsp: PERSON_FIRSTNAME_IDX. Allerdings sollten auch Suffixe möglichst sparsam eingesetzt werden und nur dort, wo sie die Verständlichkeit des Codes erhöhen - beispielsweise Variablenbezeichnungen in einem PL/SQL-Code - und wo sonst ein Namespacing-Problem auftreten könnte, z.B. Indexes und Trigger.
  3. Tabellen und Views mit einem Präfix zu versehen halte ich für falsch - ausser bei Datenmodifikationen verhalten sich beide Objekte genau gleich. Und alle Tools wissen, ob es sich bei einem Objekt um eine Tabelle handelt oder eine View (oder ein Snapshot oder was es sonst noch gibt!) Ausserdem ist es manchmal klug, bei Views und Tabellen einen Namespacing-Konflikt zu haben, um eine unterschiedliche Namensgebung zu erzwingen (TBLPERSON und VIEWPERSON suggeriert denselben Inhalt, was aber überhaupt nicht sein muss!)
  4. Statt Indexes zu nummerieren halte ich es für sinnvoller, das indexierte Feld in den Namen einzubeziehen, also z.B. PERSON_FIRSTNAME_IDX (statt IDX_PERSON_01)
  5. Für Feldbezeichnungen halte ich die Typenangabe als komplett verfehlt. Erstens verunstaltet sie den Feldnamen, zweitens ist sie immer unvollständig und drittens muss man sowieso in der Tabellendefinition nachschauen, welches Feld man wie ausfüllen soll - also unnötige Arbeit. Ausnahmen: CRE_DATE, MOD_DATE etc. da dadurch einfacher verstanden wird, was in diesem Feld gespeichert wird. CRE_DATE liest sich doch schneller und einfacher als DTCREACTION, oder?

Kommentar von Anton Müller

  1. Identifier welche GrossBuchstaben mittendrin, haben sind schlecht einzutippen und häufig vertippt man sich auch. (e.g. MachineBackupHistory.pm)
  2. Identifier welche nur aus GROSSBUCHSTABEN bestehen sind unleserlich, da der geübte Leser in seinem Leben zu 99% Kleinbuchstaben liest.
  3. Was die EnglischSprachigkeit betrifft bin ich voll dafür, vorausgesetzt es wird nicht SwEnglish verwendet. (e.g. Mensa does not exist and Mensas is definitely not Menses)
  4. Der selbstdokumentierende Code ist fast immer eine Entschuldigung für eine fehlende Dokumentation !
  5. Was für mich häufig ein Problem ist: wann Singular und wann Plural. Leider schweigt sich der Vorschlag dazu aus.
  6. Bei der TabellenDefinition sehe ich nicht klar wieso "PRIMARY KEY" und "INDEX", nicht aber "not null" und "default".
  7. Swen's Vorschläge halte ich für realistischer. Sie sind auch mit Praxis des DBI Gebrauchs und der Perlprogrammierung besser zu vereinbaren.;

Kommentar von Doris Tomaschewski-Walser

  1. Präfixes vor Namen finde ich generell schlecht wegen der Lesbarkeit. Suffuxe kann ich bei Tabellen und Primärschlüsseln befürworten, am liebsten mit _ Unterstrich getrennt.
  2. Ich würde generell Kleinschreibung bevorzugen.
  3. Wie Swen finde ich es auch besser, wenn der Name in das indizierte Feld mitaufgenommen wird, falls der Index nicht nur für den internen Gebrauch vorgesehen ist.
  4. Typenangaben würde ich bei Feldnamen generell weglassen, die Felddefinitionen habe ich stets vor mir liegen, wenn ich sie benoetige.
  5. Zur Frage Singular/Plural: Lasst uns generell den Singular verwenden, denn der Feldname bezieht sich auf je 1 Tupel resp. Datensatz.

Also: person_tbl person_id name firstname creation person_01 person_firstname_01

Kommentar Benno Luthiger

Mein Ansatzpunkt ist, dass über die Modellierung von Datenbanken bzw. Datenbankschemen auf der Basis von Datenmodellen, d.h. von bildlichen Darstellungen der Tabellen inkl. Felder und deren Relationen diskutiert wird. Als Beispiel habe ich einen Ausschnitt aus einem Datenmodell angehängt. Idealerweise wird zur Datenmodellierung ein entsprechendes Modellierungs-Tool benutzt, welches sicherstellt, dass die graphische Darstellung mit den Tabellen-Definitionen synchronisiert ist, d.h. die Create-Scripts für das Datenbankschema sind nur eine spezielle Darstellung des Datenmodells wie es auch die visuelle Darstellung ist. Die bildliche Darstellung soll folgenden Zwecken dienen:

  • Dokumentation des Datenmodells: Eine Person, die neu die Wartung der Daten übernimmt, soll mit dieser Darstellung das Datenmodell begreifen können.
  • Hilfsmittel für die Diskussions des Datenmodells: Die Darstellung soll die Verifikation von Fragen erlauben wie: Sind alle notwendigen Daten vorhanden? Sind alle Daten normailisiert? Wie kann ich gewisse Daten abfragen?

Auf dieser Grundlage macht es meiner Meinung nach Sinn, sowohl Gross-Klein-Schreibung zu verwenden, wie auch Feldnamen mit einem kurzen Präfix zu versehen. Gross-Klein-Schreibung erleichtert die Lesbarkeit des Datenmodells. Wenn die Datenbank selbst nicht zwischen Gross- und Kleinbuchstaben unterscheidet, so scheint mir das kein Problem zu sein, solange die Datenbank die Objekte korrekt erzeugt und die Abfragen korrekt ausführt.

Eine grobe Typenbezeichnung den Feldnamen beizufügen, erscheint mir ebenfalls sinnvoll: Für eine Diskussion und Dokumentation ist es oft wichtig zu wissen, ob ein bestimmtes Feld vom Typ String, Zahl, Datum oder BLOB ist. Je nachdem ändert sich die Bedeutung von ADD, CONCAT etc., auch wird möglicherweise der Zugriff anders bzw. es müssen Daten konvertiert werden.

Für die Typenbezeichnung einen Präfix zu verwenden macht Sinn, weil so auf einen Blick sichtbar wird, ob eine Feld ein Schlüssel ist oder nicht. Da der Primärschlüssel in einer Tabelle immer numerisch ist, braucht es keine Typenbezeichnung. Ein Primärschlüssel von Tabelle X kann in der Tabelle Y als Fremdschlüssel auftreten. Da er keinen Suffix hat, wird seine Bedeuthung sofort offensichtlich.

Ich habe den Eindruck, dass Swen eine andere Situation vor Augen hat, wenn er Tabellendefinitionen nachschaut, um Felder auszufüllen. Mir geht es um die Datenmodellierung, um die Diskussionen, die dabei notwendig sind und die Dokumentation dieses Prozesses. Steht das Datenmodell, dann füllt mein Persistenz-Layer die Felder aus und ich brauch mit nicht mehr darum zu kümmern.

Selbstdokumentierender Code ist keine Entschuldigung für eine Dokumentation, sondern eine ideale Ergänzung. Dokumentation hat die Tendez, nicht synchron zu sein mit dem zu dokumentierenden Gegenstand. Ist der Gegenstand so designed, dass er selbst dokumentierend ist, so wird eine Quelle von Missverständnissen eliminiert.

weitere Anmerkungen von Swen

Mit einer bildlichen Darstellung eines DB-Schemas gewinnt am schnellsten einen Überblick, keine Frage. Wenn man im DB-Schema von Benno die Präfixe weglässt, gewinnt es nochmals deutlich an Übersicht und Lesbarkeit. Die Datentypen interessieren nur den Programmierer, der eine Schnittstelle programmieren muss - und der kommt um eine separate, detaillierte Tabellendefinition sowieso nicht herum. Oracle kennt übrigens über 20 verschiedene Datentypen! Für denjenigen, der einen Überblick gewinnen möchte, ist vor allem eines wichtig: Was (d.h. welche Werte) sind in diesem Feld abgespeichert? Deshalb ist eine klare und eindeutige Wahl der Feldnamen enorm wichtig. Beispiele:

  • FAMILYNAME statt NAME
  • CREATION_DATE oder CRE_DATE oder CRE_BY statt nur CREATION
  • DEPARTMENT statt SECTION (section ist weniger meiner Ansicht nach weniger präzis)

Kleinschreibung würde ich ebenfalls bevorzugen, Oracle konvertiert aber leider alle Objekte in Grossbuchstaben frown Für Tabellennamen sollte immer der Singular verwendet werden. Bei Feldnamen kann es auch Plural geben, z.B. "REMARKS", aber das sind wohl eher Ausnahmen. Arrays: immer Plural. Hashes: Singular (mit Ausnahmen).

Primärschlüssel sind nicht immer numerisch. Und sie haben meist einen Suffix, nämlich "ID". Ein gute graphische Darstellung eines DB-Schemas verbindet die Fremd- und Primärschlüssel so, dass dieser Sachverhalt klar ersichtlich ist (tut mir leid Benno, aber die graphische Darstellung Deines Datenmodellierungs-Tools überzeugt mich diesbezüglich nicht besonders...) Wichtig scheint mir, dass die Datenmodellierung nicht als einmaliger Akt angesehen wird - Änderungen und Erweiterungen sind sozusagen "vorprogrammiert". Wenn ich Änderungen an einer Tabelle mache, dann benutze ich jeweils ein graphisches Klicki-Tool, das Skript dazu kann die Datenbank ja jederzeit automatisch generieren. Wenn ich mit so einem Tool aus 100 Tabellen meine Tabelle TBLPERSON suchen muss, dann tun mir nachher die Augen weh. Nochmals: bitte keine Präfixe.

Was leider oft fehlt, ist Prosa. Weshalb wurde dieses DB-Schema gewählt? Welches sind die zentralen Tabellen? Was sind die wichtigsten Ideen, die zu diesem Schema geführt haben? In diesem Sinne brauchen wir Dokumente, die wir einem Neuling in die Hand drücken und sagen können: "Da, lies' mal!"

Topic attachments
I Attachment History Action Size Date Who Comment
PDFpdf DB_StyleGuide.pdf r1 manage 24.0 K 2007-04-18 - 06:35 PeterBircher  
GIFgif DatamodelExtract.gif r1 manage 33.3 K 2007-04-23 - 10:07 BennoLuthiger  
Topic revision: r2 - 2010-12-21 - vermeul
 
This site is powered by the TWiki collaboration platform Powered by PerlCopyright © 2008-2017 by the contributing authors. All material on this collaboration platform is the property of the contributing authors.
Ideas, requests, problems regarding TWiki? Send feedback