Laden...

"Patterns & Practises" - Zur Nomenklatur von Datenbanken, Tabellen und Feldern

Erstellt von CarstenP vor 19 Jahren Letzter Beitrag vor 19 Jahren 10.620 Views
C
CarstenP Themenstarter:in
65 Beiträge seit 2004
vor 19 Jahren
"Patterns & Practises" - Zur Nomenklatur von Datenbanken, Tabellen und Feldern

Sodale, ich wollte die "Patterns & Practises", also hier mal eine Praktik zur Benennung von Datenbanken, Tabellen und Feldern.

Grundsätze
Der Grundsatz bei der Benennung ist stets, dass die Namen selbstdokumentierend sein sollten. Das vorgestellte Schema ist bereits Jahrzehnte alt (ja, wirklich) und stammt noch aus Mainframe-Zeiten. Es mag auf den ersten Blick umständlich erscheinen (so umständlich etwa, wie eine Variable "vorname" statt "vn" zu nennen), führt jedoch zu sehr lesbaren SQL-Statements.

1. Datenbank-Name
Oft ist der Name einer Datenbank vorgegeben, z.B. bei Datenbanken, die auf einem Webserver per Web-Interface erstellt werden. Dann treffen die hier gemachten Vorschläge natürlich nicht zu.

Wenn der Name frei zu vergeben ist, sollte er aus zwei Teilen bestehen, die zusammen den Sinn der Datenbank komplett dokumentieren. Bei sehr großen Datenbanken (groß iSv "bildet viel ab") kann auch ein Begriff den Sinn der Datenbank beschreiben.

Beispiele:*CustomerRelations *SourcecodeRepository *myCSharp

2. Tabellen-Namen
Der Name einer Tabelle reflektiert den Inhalt. Das klingt erstmal trivial, ist aber oft vernachlässigt. Enthält die Tabelle also Produkte, so heißt die Tabelle konsequent "Produkte" oder "Products" (und nicht anders!).

Die (quasi-)englische Variante ist aus einem einfachen Grund zu bevorzugen: Englische Plural-Bildung besteht idR aus dem einfachen Anhängen eines "s", während die deutsche Plural-Bildung sehr unregelmäßig ist.

Warum "quasi"? Weil man sich von der grammatisch korrekten Plural-Bildung bei den Ausnahme-Fällen trennt. So wird aus einer Tabelle, die Städe beinhaltet, also eigentlich "cities", dennoch "Citys". Der Sinn wird später klar.

3. Feld-Namen
Das Thema der Feld-Benennung ist am komplexesten, aber es gibt klare Regeln, die nur eins fordern: keine Ausnahmen.

Eine Zeile (Row, Record) beinhaltet die Information zu einem Objekt. Deswegen beginnt der Name eines Feldes prinzipiell mit dem Singular des Tabellen-Namens. Wenn also die Tabelle "Persons" heißt, beginnt der Name jedes Feldes mit "Person". Die weitere Benennung ist Geschmacksache. Für bestimmte Datentypen gibt es jedoch sinnvolle Konventionen:*ID - "PersonID" *bool'sche Werte - sind entweder "is"s oder "has"s: "PhoneNoIsSMSCapable" (Tabelle "PhoneNos"); "ComputerHasInternetAccess" (Tabelle "Computers"). *Datum-/Uhrzeit-Werte - enden - wenn der Feldname nicht bereits selbstredend ist - auf "At" oder "On" auf "From" oder "To" oder "Until", ggf. ergänzt um "D", "T" oder (nach eigenem Geschmack) "DT", wobei "D" einen reinen Datumswert, "T" einen reinen Zeitwert (time) und "DT" einen kombinierten Datum-Zeit-Wert markieren: "EventCreatedAt" (Datum-Zeit-Wert); "PersonBirthdate" (Datums-Wert, keine Ergänzung nötig); "AlertRememberAgainAtT" (Zeit-Wert). *Referenz-IDs (foreign keys) - werden durch den Singular der referenzierten Tabelle und "RFID" oder "PID" (pointer to ID) gekennzeichnet ("PersonAddressPID").

Der Sinn dahinter ist nicht, möglichst lange Feldnamen zu erzeugen, sondern Feldnamen, die sich selbst erklären. Das Feld "PersonGender" kann nur zur Tabelle "Persons" gehören. Dies erlaubt auch, halbautomatisierte Verfahren zur Erstellung von Tabellen, SQL-Abfragen usw. einzusetzen (deswegen der "Quasi-Plural"). Außerdem erübrigt es sich, in SQL-Abfragen Feldnamen durch den Tabellennamen zu qualifizieren:

SELECT Persons., Addresses. FROM Persons, Addresses WHERE AddressID = PersonAddressPID

4. Referenz-Tabellen (n:m-Zuordnungen)
Hier gibt es keine feste Regel zur Benennung. Ich persönlich verwende zur Kennzeichnung einer solchen Tabelle ein führendes "x": xCompanysProducts, und kürze beim Feld dann ab: xCPCompanyPID und xCPProductPID.

/// <summary>
/// Signatur
/// </summary>

X
2.051 Beiträge seit 2004
vor 19 Jahren

Im Grunde genommen, bin ich einverstanden.

Punkt 3 (Feld-Namen) will ich aber bestreiten.
Tabellenname in Feldbezeichnung aufzunehmen, bringt wirklich keinen Vorteil und macht nur Feldernamen länger. Und wenn man bei JOIN-Abfragen Tabellennamen dem Spaltennamen vorsetzt, wird der Name nur um einen Punkt länger und man sieht genauso gut welche Spalte welcher Tabelle gehört, sogar besser.

SELECT Persons., Addresses. FROM Persons, Addresses WHERE Addresses.ID = Persons.AddressesPID

Damit erübrigt sich auch "Quasi-Plural" (Cities = Citys).
Das hat aber noch weitere Vorteile. Man kann z.B. in der Anwendung die Spalten so nehmen, wie sie sind (sieh mal DataGrid an).

und es hindert in keiner Wiese das halbautomatisierte Verfahren zur Erstellung von Tabellen, SQL-Abfragen usw.

333 Beiträge seit 2004
vor 19 Jahren

Also in Punkt 3 bin ich der selben Meinung wie Xggene. Wir verwenden dieses Benennungssystem auch teilweise. Und spätestens wenn man längere Tabellennamen hat wirds einfach ätzend die Feldnamen immer komplett voranzuschreiben. Die Tabelle mit Punkt dem Feld voran zu schreiben funktioniert genauso gut und man spart sich, wenn notwendig über Aliase, Platz und Nerven. Außerdem resultieren daraus weniger Probleme beim Ändern von Tabellennamen.

Ansonsten hörts sich alles ganz gut an 🙂

([bb]|[^b]{2})

C
CarstenP Themenstarter:in
65 Beiträge seit 2004
vor 19 Jahren

Ich widerspreche dem Widerspruch nur ungerne, aber dennoch begründet. 😉

Das vorgestellte Schema ist nicht speziell auf C#/.NET zugeschnitten, sondern soll möglichst allgemeingültig sein (und findet nur bei älteren DBs seine Grenzen, wenn diese DBs Tabellen- und Feldnamen auf x Zeichen begrenzen, wie etwa dBase III).

Beispiel: MySQL + PHP:

$sql = "SELECT Persons.*, Addresses.* FROM Persons, Adresses
        WHERE Person.AddressPID = Address.ID";
$result = mysql_query($sql, $conn);
$row = mysql_fetch_row($result);

Dieser Code würde "unexpected results" liefern, da die MySQL-Abfrage-Engine die Feldnamen nicht qualifiziert. Wenn man auf $row nun nicht per numerischem Index, sondern über den Feldnamen zugreift, rauscht's, denn es gibt zwei Felder, die "ID" heißen. Was also ist denn nun $res["ID"]? Die Person-ID oder die Address-ID?

/// <summary>
/// Signatur
/// </summary>

X
2.051 Beiträge seit 2004
vor 19 Jahren

ich kenne mich mit MySql nicht aus, um die Sache mit Feldname zu bestätigen/widersprechen.

Aber es gibt für solche Fälle so genannte Aliase. Und ich bin mir sicher, das kann sogar MySql.

C
CarstenP Themenstarter:in
65 Beiträge seit 2004
vor 19 Jahren

Hm, Du findest also

SELECT Persons.ID AS PersonID, Persons.FirstName, Persons.LastName, Persons.Birthdate, ..., Addresses.ID AS AddressID, Addresses.Street, Addresses.City, Addresses.ZIP, ... FROM [...] WHERE [...]

lesbarer als

SELECT Persons., Addresses. FROM [...] WHERE [...]

? Okay...

Ist aber wie immer Geschmacksache, wie man das handhabt. Ich halte mich ja auch nicht an alle Patterns & Practises, die irgendwo durchs Netz spuken. Wenn man Regeln kennt und verstanden hat, darf man sie natürlich brechen 😉

/// <summary>
/// Signatur
/// </summary>

X
2.051 Beiträge seit 2004
vor 19 Jahren

* in den SQL Abfragen habe ich mir schon vor langer Zeit abgewöhnt, da es meistens nur unnötig Daten über die Leitung fließen lässt. Man glaubt nicht, wie viel Performance das kosten kann.

333 Beiträge seit 2004
vor 19 Jahren

Mit dem leserlich und unleserlich ist Ansichtsache. Einfache Statements werden durch das voranstellen des Tabellennames vor Feldnamen auch unnötig in die länge gezogen:


SELECT AddressID, AddressFirstName, AddressLastName, AddressCity FROM Address
WHERE AddressID > 1000 AND AddressID < 2000 AND AddressCountry = 4711

anstatt:

SELECT ID, FirstName, LastName, City FROM Address
WHERE ID > 1000 AND ID < 2000 AND Country = 4711

Bei Joins lässt sich mit dem Tabellennamen und dem Punkt notfalls ein Feld näher qualifizieren. Und mit "As" lassen sich dann eben auch Verwirrungen beim auslesen vermeiden. Ich mein "Address" ist auch noch ein relativ kurzer Tabellenname, aber wenn du dann einen Namen von 20 Zeichen und mehr hast is das nicht mehr lustig. Dadurch werden Statements total unleserlich, finde ich.

([bb]|[^b]{2})

C
CarstenP Themenstarter:in
65 Beiträge seit 2004
vor 19 Jahren

Ja, wie gesagt, es ist eben Geschmacksache. Ich benutze JOINs nur dann, wenn es gar nicht mehr anders geht (und es geht sehr oft ohne). *-Abfragen habe ich öfter dann, wenn es drum geht, Basisdaten zu ändern, also zB ne Adresse. Da werde ich, weil ich 2 von 12 Feldern nicht brauche, die beiden Felder nicht weglassen. Bisschen faul bin ich dann doch 😉

/// <summary>
/// Signatur
/// </summary>

C
980 Beiträge seit 2003
vor 19 Jahren

du magst wohl das R von RDBMS nicht wirklich? 😉

C
CarstenP Themenstarter:in
65 Beiträge seit 2004
vor 19 Jahren

Stimmt, ich bin mehr für das O² zu haben, also OODBMS 😉 Noch mehr wäre ich für ein "Entity-oriented DBMS" zu gewinnen, aber was soll's, man kann nicht alles haben 😉

/// <summary>
/// Signatur
/// </summary>