Datenbank: Entity mit vielen Referenzen? Ansatz so ok?

Bitte aktiviere JavaScript!
Hallo zusammen,

mich würde heute folgendes interessieren:
Ich habe eine Entity, die viele Referenzen haben kann, also als Beispiel:
- Entity Note kann 1....n ReferenzObjekte haben

ReferenzenObjekte können sein: Angebot, Rechnung, Bild, Gutschrift
-> Im Endeffekt alle Entities meiner Anwendung (und das sind mittlerweile 70-80)

Ich könnte nun natürlich eine Tabelle ReferenzObjekte anlegen, die für jede Entity einen FK - Schlüssel hat:
Rechnung_FK, Angebot_FK usw.
-> Das Problem ist aber, dass MSSQL hier bei 64 Fremdschlüsseln ein Problem hat.

Ich habe das nun so gelöst:
ReferenzObjekte
- ID
- String EntityName
- String ObjectId

- EntityName ist dann jeweils immer di Entität. Also z.B. für "Rechnung" wird dann eben "Rechnung" als String hineingeschrieben
- ObjectId ist die ID von der Rechnung

Will ich nun die Referenz holen, suche ich mit "EntityName" und "ObjectId" und bekomme dann für Rechnung bspw:
EntityName = Rechnung
ObjectId = 1
-> die Rechnung 1.

Das funktioniert auch alles so. Aber die Frage ist für mich, kann man diesen Ansatz zu wählen oder wird mir das früher oder später ein Problem geben (Stichwort Performance bspw.) ?

Danke für die Hilfe
 
A

Anzeige


Vielleicht hilft dir dieser Kurs hier weiter: (hier klicken)
Was verstehst du nicht genau?
Das ist eine Tabelle, die eben die Referenzen zu anderen Tabellen nicht als FK abspeichert, sondern eben über einen eindeutigen EntityName und der ID von dieser Tabelle....
Die entsprechende Entity wird dann eben über die EntityName und ID geladen...
 
Kannst du dein Beispiel nicht einfach mal auf 3-5 Entitäten runterbrachten und erklären was die Software da eigentlich machen soll. Ich kapier es nämlich nicht wozu man so ein Konstrukt braucht,
 
Also:
- Ich habe eine Entität bzw. Tabelle "Notizen":

Eine Notiz kann zu folgenden Entitäten angehängt werden:
- Rechnung
- Angebot
- Gutschrift
- Bild
- Brief
- Kunde
- Lieferant
- Brief
- Email
- Mitarbeiter
- Urlaubsantrag
- .........

Ich kann nun natürlich für jedes dieser Entitäten einen FK in der Tabelle Notiz anlegen.
-> Ich habe aber etliche Entitäten und laufe dann in die Gefahr, dass MSSQL mir hier einen Strich durch die Rechnung macht, da ich nur 64 FK pro Entität hinzufügen kann

-> Eine eigene Notiz-Tabelle pro Entität erachte ich für Schwachsinn. Also RechnungNotiz z.B.

Daher mein Ansatz:
Tabelle ReferenceObject als Tabelle anlegen.
Diese hat:
- EntityName (hier steht dann "Rechnung")
- objectId (Id der Rechnung)

Wenn ich nun von einer Rechnung mit der ID 1 die Notizen abrufen will, dann frage ich in der WHERE Clause ab mit:
WHERE t.entityName = 'RECHNUNG' and m.objectId =1

Soweit verständlich?
 
Ah jetzt kann man das verstehen.

Dann würde ich das wahrscheinlich genauso lösen. Entityname würde ich dann aber den tabellennamen nehmen und nicht irgendeinen lokalisierten String. Aber vielleicht machst du das ja tatsächlich alles in deutsch (was in meinen Augen dann der große Fehler wäre)

Gruß

Claus
 
Ok, danke.
Ich habe in jeder Entität eine Konstante als String, die mir den Namen ausgibt:
public final String ENTITY_NAME = "Offer";
Ja, die Namen sind auf Englisch.

Eine abschließende Frage:
objectId: sollte das ein Long sein (wie die ID in den jeweiligen Klassen) oder kann es auch ein String sein (Performance)?
 
Ich würde keinen String benutzen. Warum? Ich hoffe doch das die id in den anderen Tabellen ein

Int auto increment unsigned primary key

Ist?

Gruß

Claus
 
Ich habe aber etliche Entitäten und laufe dann in die Gefahr, dass MSSQL mir hier einen Strich durch die Rechnung macht, da ich nur 64 FK pro Entität hinzufügen kann
Wie kommst Du auf die Einschränkung von 64? Wenn ich https://docs.microsoft.com/en-us/sql/sql-server/maximum-capacity-specifications-for-sql-server?view=sql-server-2017 richtig interpretiere, dann kannst Du 253 FKs je Tabelle angeben und eine Tabelle kann Teil von 10.000 FKs sein. Für Dich interessant wären ja die 10.000....

objectId: sollte das ein Long sein (wie die ID in den jeweiligen Klassen) oder kann es auch ein String sein (Performance)?
Kein String.

Mal zurück zum Problem. Du behandelst die Notiz ja wie ein Attachment, die an eine Entity angehängt wird. Wenn wir also den einfachen Fall betrachten, dann hättest Du eine Tabelle RechnungNotiz und eine Tabelle Rechnung, wobei jeder Satz in RechnungNotiz einen Satz aus Rechnung referenziert. Die Rechnung weiß gar nichts von RechnungNotiz. Gleiches würde dann für Angebot und AngebotNotiz usw. gelten.

Du willst aber nicht für jede Entity eine eigene Notizen-Tabelle, sondern alle Notizen in einer Tabelle speichern. Die Frage ist jetzt, was eine Notiz dann referenziert.

Zu diesem Zweck hast Du ein ReferenzObjekt eingeführt. Damit kannst Du den FK Notiz -> ReferenzObjekt darstellen. In ReferenzObjekt speicherst Du einen weiteren, eindeutigen Schlüssel, der sich aus dem Namen und der ID der betreffenden Entity zusammensetzt. Für diesen Schlüssel kannst Du aber keine FKs ReferenzObjekt -> Rechnung, ReferenzObjekt -> Angebot usw. anlegen.

Man kann ReferenzObjekt auch als die "Basisklasse" aller Referenzobjekte betrachten. Die Identität des konkreten Referenzobjekts, also der betreffenden Entity, ist somit durch die Identität des Referenzobjekts gegeben. Die Angabe des Tabellennamens ist "lediglich" Zusatzinfo (=> konkreter Subtyp), um gezielt Daten abrufen zu können.

Das ReferenzObjekt braucht dann nur zwei Spalten (ID und Tabellenname). Die ID der Entity ist damit immer gleich der ID des Referenzobjekts. Der FK geht dann von Entity zu ReferenzObjekt.

Beim Erzeugen einer Rechnung muss dann in einer Transaktion erst ein Referenzobjekt (soz. als ID der Entity) angelegt und dann die dazugehörige Entity gespeichert werden. Das könnte man per Trigger lösen (sofern man nicht einen ORM verwendet, der das für einen erledigt).

Hat alles Vor- und Nachteile.
 
Passende Stellenanzeigen aus deiner Region:

Neue Themen

Oben