Relationen zweiter Generation

Relationen zweiter Generation

am 09.11.2006 00:52:30 von Tobias Fratnik

Hi NG!

Also, vereinfacht:

table 'events'
uid | date

table 'e_p_allocation'
uid | event_id | participant_id

table 'e_t_allocation'
uid | event_id | topic_id

table 'partipicants'
uid | name

table 'agenda'
uid | topic

Das ist der Aufbau, brav normalisiert. ;-) Ich will: Events anhand des
Datums auswählen, die Namen der Teilnehmer und die Themen der Agenda.
Welche Ansätze sind hier die praktibelsten? Mehrere Abfragen und
Verknüpfung durch das Frontend gingen zwar, wären aber wahrscheinlich
dich unperformanteste Lösung.

TIA,

Tobias

Re: Relationen zweiter Generation

am 09.11.2006 09:26:04 von Thomas Rachel

Tobias Fratnik wrote:

> table 'events'
> uid | date
>
> table 'e_p_allocation'
> uid | event_id | participant_id
>
> table 'e_t_allocation'
> uid | event_id | topic_id
>
> table 'partipicants'
> uid | name
>
> table 'agenda'
> uid | topic

Ich schätze mal, uid ist die ID innerhalb der jeweiligen Tabelle?

Das Feld date ist ungünstig benannt, da es sich um einen reservierten
Bezeichner handelt, der bei Verwendung als Feldbezeichner daher gequotet
werden muß.

> Das ist der Aufbau, brav normalisiert. ;-) Ich will: Events anhand des
> Datums auswählen, die Namen der Teilnehmer und die Themen der Agenda.

SELECT
name,topic
FROM
events
JOIN e_p_allocation epa ON events.uid=epa.event_id
JOIN participiants ON participiants.uid=epa.participiant_id
JOIN e_t_allocation eta ON events.uid=eta.event_id
JOIN agenda ON agenda.uid=eta.topic_id
WHERE `date` BETWEEN $dann AND $dann;

So in der Art?


> Welche Ansätze sind hier die praktibelsten? Mehrere Abfragen und
> Verknüpfung durch das Frontend gingen zwar,

die hättest Du ja auch hier hinschreiben können - vielleicht waren sie ja
auch absolut korrekt.


> wären aber wahrscheinlich dich unperformanteste Lösung.

wie kommst Du darauf? Wenn sie langsam waren, haben Dir vermutlich ein
paar Indices gefehlt.

Du brauchst grob gesagt im Prinzip Indices auf jedes Feld, welches an
einem JOIN teilnimmt oder für das eine WHERE-Bedingung existiert.

Hier also:
- auf `date` für die WHERE-Bedingung
- eigentlich auch auf events.uid (da gehört eh ein PRIMARY KEY hin), aber
der würde hier nicht verwendet
- jeweils auf e_?_allocation.event.id - das gegenüberliegende besser
auch, die würden hier aber ebenfalls nicht verwendet
- und dann natürlich mindestens auf agenda.uid und participiants.uid,
auch als PRIMARY KEY.

Falls Du auch nach anderen Kriterien suchen willst ("an welchen
Veranstaltungen nimmt Teilnehmer XYZ teil?), solltest Du auch die
entsprechenden Indices erstellen - und hier kommen dann auch die oben
als "wird hier nicht verwendet" deklarierten ins Spiel.


Thomas

Re: Relationen zweiter Generation

am 09.11.2006 13:24:49 von Tobias Fratnik

Thomas Rachel schrieb:
> Tobias Fratnik wrote:
>
>> table 'events'
>> uid | date
>>
>> table 'e_p_allocation'
>> uid | event_id | participant_id
>>
>> table 'e_t_allocation'
>> uid | event_id | topic_id
>>
>> table 'partipicants'
>> uid | name
>>
>> table 'agenda'
>> uid | topic
>
> Ich schätze mal, uid ist die ID innerhalb der jeweiligen Tabelle?

Richtig.

> Das Feld date ist ungünstig benannt, da es sich um einen reservierten
> Bezeichner handelt, der bei Verwendung als Feldbezeichner daher gequotet
> werden muß.

Da hast Du Recht, danke für den Hinweis.

>> Das ist der Aufbau, brav normalisiert. ;-) Ich will: Events anhand des
>> Datums auswählen, die Namen der Teilnehmer und die Themen der Agenda.
>
> SELECT
> name,topic
> FROM
> events
> JOIN e_p_allocation epa ON events.uid=epa.event_id
> JOIN participiants ON participiants.uid=epa.participiant_id
> JOIN e_t_allocation eta ON events.uid=eta.event_id
> JOIN agenda ON agenda.uid=eta.topic_id
> WHERE `date` BETWEEN $dann AND $dann;
>
> So in der Art?

Sieht nicht schlecht aus. Ich wusste nicht bw. wäre nicht auf die Idee
gekommen, dass Felder aus bereits gejointen" Tabellen als Join-Bedingung
verwendet werden können.

>> Welche Ansätze sind hier die praktibelsten? Mehrere Abfragen und
>> Verknüpfung durch das Frontend gingen zwar,
> die hättest Du ja auch hier hinschreiben können - vielleicht waren sie ja
> auch absolut korrekt.

Kann ich mir schwer vorstellen. Das hätte soausgesehen, dass ich zuerst
die in Frage kommenden Events abfrage, daraus eine Liste der Event-IDs
mache und mittels derer dann einzeln (!) die Datensätze der zugehörigen
Teilnehmer bzw. Themen hole. Allerdings wäre es wohl möglich, anstatt
der Joins ein Subselect zu verwenden, und so die Teilnehmer und Themen
einzeln abzufragen (jeweils mit dem Event-SELECT-query als Subselect),
Deine Lösung find ich aber wesentlich sympatischer.

> Du brauchst grob gesagt im Prinzip Indices auf jedes Feld, welches an
> einem JOIN teilnimmt oder für das eine WHERE-Bedingung existiert.
>
> Hier also:
> - auf `date` für die WHERE-Bedingung
> - eigentlich auch auf events.uid (da gehört eh ein PRIMARY KEY hin), aber
> der würde hier nicht verwendet
> - jeweils auf e_?_allocation.event.id - das gegenüberliegende besser
> auch, die würden hier aber ebenfalls nicht verwendet
> - und dann natürlich mindestens auf agenda.uid und participiants.uid,
> auch als PRIMARY KEY.

Stimmt, mit sorgsam gewählten Indices lässt sich da bestimmt noch etwas
rausholen. Soweit war ich alleridngs noch gar nicht, mir hat das
Grundkonzept gefehlt.

Danke jedenfalls für Deine ausführliche und erleuchtende Antwort! ;-)

Grüße,

Tobias

Re: Relationen zweiter Generation

am 09.11.2006 19:58:37 von Thomas Rachel

Tobias Fratnik wrote:

> Stimmt, mit sorgsam gewählten Indices lässt sich da bestimmt noch etwas
> rausholen.

So kann man es auch formulieren. Die unmißverständlichere Formulierung
wäre jedoch "Sorgsam gewählte Indices sind das A und O einer
relationalen Datenbank".

> Soweit war ich alleridngs noch gar nicht, mir hat das
> Grundkonzept gefehlt.

Indices sind dann aber der unmittelbar zweite Schritt.


Thomas
--
Ich kenne das auch, bin ja selbst Deutscher. Ich bin kleinkariert,
bürokratisch, humorlos, obrigkeitsgläubig... Ich würde die Liste gerne
fortführen, aber ich muß erstmal meinen Gartenzwerg geraderücken, der
hat sicheben zur Seite geneigt." (Sebastian Koppehel in dsnu)