Quicknavi |
|
Generischer OR-Mapper - Manuelles Setup der Datenbank (beta)
1. Einleitung
Der OR-Mapper hält sich beim Design des Datenbank-Layouts an eine einfache Konvention:
Jedes Objekt wird in einer Tabelle abgebildet, jede Beziehung in eine weitere. Dieses
Vorgehen ist ein guter Mittelweg zwischen Normalisierung und guter Performance, da das Laden von
Objekten auf Tabellenebene schnell abgebildet werden kann, das Modell jedoch trotzdem die Generik
mitbringt, weitere Objekte hinzuzufügen - etwa wegen weiteren Modulen - und die Beziehung zwischen
diesen neuen Objekten das bisherige Layout nicht stört.
Das folgende Kapitel erklärt nun, wie die Definition der Objekte und deren Beziehungen in
Datenbank-Tabellen umgesetzt werden.
2. Umsetzung der Objektdefinitionen
Die Konfiguration der Objekte enthält im wesentlichen den Namen und die Attribute eines Objekts.
Eine typische Konfigurationsdatei enthält dabei eine beliebige Anzahl folgender Definitionen:
[{SektionsName}]
{AttributName} = "{AttributTyp}"
...
{SektionsName} ist dabei der Name des Objekts (z.B. User),
{AttributName} der Name eines Attributs des Objekts (z.B. FirstName)
und {AttributTyp} der Daten-Typ des Attributs. Beim automatischen Setup werden die
Daten-Typen
- VARCHAR({LENGTH})
- TEXT
- DATE
jeweils in die richtigen SQL-Statements übersetzt. {LENGTH} ist dabei durch
eine entsprechende Zahl (gewünschte Länge der Zeichenkette) zu ersetzen. Alle weiteren
Datentypen-Deklarationen müssen ausformuliert werden.
Für die Umsetzung der Konfiguration in einzelne Tabellen gelten folgende Regeln:
-
Der Name der Tabelle ergibt sich aus dem Namen des Objektes in Kleinbuchstaben mit dem
Prefix "ent_". Im Fall des Objekts User ergibt sich somit ein Tabellenname
ent_user.
-
Die Beziehungen zwischen Objekten werden in einer eigenen Konfiguration definiert
(siehe Kapitel 3).
-
Die Namen der Attribute eines Objekts sind identisch mit den Attributen der Konfigurationssektion.
Die Werte der Attribut-Definitionen werden zur Auslegung des Datentyps verwendet.
-
Die Namen der Attribute dürfen nicht mit reservierten Wörtern der verwendeten Datenbank
übereinstimmen. Im Fall von MySQL, kann diese Liste unter
http://dev.mysql.com/doc/refma...words.html eingesehen
werden.
-
Der Name des Primärschlüssels der Tabelle wird aus dem Namen des Objekts und dem
Suffix ID generiert. Im Fall des Objekts strong>User ergibt sich somit
der Name UserID.
3. Umsetzung der Beziehungsdefinitionen
Die Konfiguration der Objekte enthält im wesentlichen den Namen und die Qualität der
Beziehung sowie das referenzierte Quell- und Zielobjekt. Bei der Auslegung der Beziehungsrichtung
muss auf die Bedeutung der Beziehung im Objektmodell geachtet werden (siehe hierzu
Dokumentation OR-Mapper, 2.3.2. Beziehungsdefinition).
Eine typische Konfigurationsdatei enthält dabei eine beliebige Anzahl folgender Definitionen:
[{SektionsName}]
Type = "{BeziehungsTyp}"
SourceObject = "{SourceObjektName}"
TargetObject = "{TargetObjektName}"
{SektionsName} ist dabei der Name der Beziehung (z.B. User2Group),
{BeziehungsTyp} die Qualität der Beziehung und {SourceObjektName}
sowie {TargetObjektName} Namen von Objekten der Objekt-Konfigurationsdatei.
Gültige Werte für Beziehungsqualitäten ({BeziehungsTyp}) sind
COMPOSITION für eine Komposition und ASSOCIATION für
Assoziationen.
Für die Umsetzung der Konfiguration in einzelne Tabellen gelten folgende Regeln:
-
Der Name der Tabelle ergibt sich aus dem Namen der Beziehung in Kleinbuchstaben und dem Präfix
cmp__ (für Kompositionsbeziehungen) oder ass__ (für
Assoziationsbeziehungen).
-
Der Primärschlüssel der Beziehungstabelle ergibt sich aus der Qualität der Beziehung.
Er lautet CMPID (für Kompositionsbeziehungen) oder ASSID
(für Assoziationsbeziehungen).
-
Die Beziehungstabelle muss jeweils eine Refrenz auf den Primärschlüssel der Quell- und
Ziel-Objekt-Tabelle besitzen. Die Namen der Fremdschlüsselspalten werden identisch den
Namen der Fremdschlüssel-IDs gewählt.
-
Über die beiden Fremdschlüssel-Spalten wird ein Index gelegt, der den JOIN-Index
darstellt. Hier ist wichtig, dass der Index über beide Spalten gelegt wird, da somit eine
höhere Selektivität des Indizes beim JOIN erreicht werden kann.
4. Beispiel
Das vorliegende Kapitel möchte je ein Beispiel für die Umsetzung von Objekt- und
Beziehungsdefinition in Datenbanktabellen geben.
4.1. Objektdefinition
Für die Objektdefinition
[Application]
DisplayName = "VARCHAR(100)"
[User]
DisplayName = "VARCHAR(100)"
FirstName = "VARCHAR(100)"
LastName = "VARCHAR(100)"
StreetName = "VARCHAR(100)"
StreetNumber = "VARCHAR(100)"
ZIPCode = "VARCHAR(100)"
City = "VARCHAR(100)"
EMail = "VARCHAR(100)"
Phone = "VARCHAR(100)"
Mobile = "VARCHAR(100)"
Username = "VARCHAR(100)"
Password = "VARCHAR(100)"
[Group]
DisplayName = "VARCHAR(100)"
erwartet der OR-Mapper die Tabellen-Definition
CREATE TABLE IF NOT EXISTS `ent_application` (
`ApplicationID` tinyint(5) NOT NULL auto_increment,
`DisplayName` varchar(100) NOT NULL default '',
`CreationTimestamp` timestamp NOT NULL default CURRENT_TIMESTAMP,
`ModificationTimestamp` timestamp NOT NULL default '0000-00-00 00:00:00',
PRIMARY KEY (`ApplicationID`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
CREATE TABLE IF NOT EXISTS `ent_group` (
`GroupID` tinyint(5) NOT NULL auto_increment,
`DisplayName` varchar(100) NOT NULL default '',
`CreationTimestamp` timestamp NOT NULL default CURRENT_TIMESTAMP,
`ModificationTimestamp` timestamp NOT NULL default '0000-00-00 00:00:00',
PRIMARY KEY (`GroupID`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
CREATE TABLE IF NOT EXISTS `ent_user` (
`UserID` tinyint(5) NOT NULL auto_increment,
`DisplayName` varchar(100) NOT NULL default '',
`FirstName` varchar(100) NOT NULL default '',
`LastName` varchar(100) NOT NULL default '',
`StreetName` varchar(100) NOT NULL default '',
`StreetNumber` varchar(100) NOT NULL default '',
`ZIPCode` varchar(100) NOT NULL default '',
`City` varchar(100) NOT NULL default '',
`EMail` varchar(100) NOT NULL default '',
`Phone` varchar(100) NOT NULL default '',
`Mobile` varchar(100) NOT NULL default '',
`Username` varchar(100) NOT NULL default '',
`Password` varchar(100) NOT NULL default '',
`CreationTimestamp` timestamp NOT NULL default CURRENT_TIMESTAMP,
`ModificationTimestamp` timestamp NOT NULL default '0000-00-00 00:00:00',
PRIMARY KEY (`UserID`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
Als Storage-Engine kann auch INNODB verwendet werden.
4.2. Beziehungsdefinition
Für die Beziehungsdefinition
[Application2Group]
Type = "COMPOSITION"
SourceObject = "Application"
TargetObject = "Group"
[Group2User]
Type = "ASSOCIATION"
SourceObject = "Group"
TargetObject = "User"
[Application2User]
Type = "COMPOSITION"
SourceObject = "Application"
TargetObject = "User"
erwartet der OR-Mapper die Tabellen-Definition
CREATE TABLE IF NOT EXISTS `ass_group2user` (
`ASSID` tinyint(5) NOT NULL auto_increment,
`GroupID` tinyint(5) NOT NULL default '0',
`UserID` tinyint(5) NOT NULL default '0',
PRIMARY KEY (`ASSID`),
KEY `JOININDEX` (`GroupID`,`UserID`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
CREATE TABLE IF NOT EXISTS `cmp_application2group` (
`CMPID` tinyint(5) NOT NULL auto_increment,
`ApplicationID` tinyint(5) NOT NULL default '0',
`GroupID` tinyint(5) NOT NULL default '0',
PRIMARY KEY (`CMPID`),
KEY `JOININDEX` (`ApplicationID`,`GroupID`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
CREATE TABLE IF NOT EXISTS `cmp_application2user` (
`CMPID` tinyint(5) NOT NULL auto_increment,
`ApplicationID` tinyint(5) NOT NULL default '0',
`UserID` tinyint(5) NOT NULL default '0',
PRIMARY KEY (`CMPID`),
KEY `JOININDEX` (`ApplicationID`,`UserID`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
Als Storage-Engine kann auch INNODB verwendet werden.
Kommentare
Möchten Sie den Artikel eine Anmerkung hinzufügen, oder haben Sie ergänzende Hinweise? Dann können Sie diese hier einfügen. Die bereits verfassten Anmerkungen und Kommentare finden Sie in der untenstehenden Liste.
Für diesen Artikel liegen aktuell keine Kommentare vor.
|