[gelöst] BCNF-Verletzung durch nichttriviale Abhängigkeit

Einklappen
X
 
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

  • [gelöst] BCNF-Verletzung durch nichttriviale Abhängigkeit

    Hallo liebe Experten,

    ich stehe vor folgender Frage: sollte ich die BCNF verletzen, wenn die funktionale Abhängigkeit zu komplex ist, um sie bei der Abfrage als triviale Where-Klausel zu formulieren?

    Die betreffende Relation ist ein Anrufer:

    Code:
    id
    form_of_address_fkey => form_of_address.id (Anrede: Frau/Herr)
    address_fkey         => address.id
    phone_number_fkey    => phone_number.id
    first_name
    last_name
    company_name
    title                (akad. Titel, z. B. "Prof. Dr.")
    is_distinguishable   (siehe unten)
    Das Attribut is_distinguishable speichert, ob der Anrufer anhand der aufgenommenen Informationen beim nächsten Anruf relativ eindeutig wiedererkennbar ist. Diese Bedingung soll als erfüllt gelten, wenn mindestens
    a) address_fkey oder
    b) phone_number_fkey oder
    c) zwei der Attribute { first_name; last_name; company_name; title }
    gesetzt sind.

    Damit ist das Attribut is_distinguishable zwar funktional von allen anderen abhängig und damit redundant, hat aber durchaus seine Berechtigung, denn die Where-Klausel würde über 3 Zeilen gehen und verlangsamt die Abfrage auch maßgeblich.

    Was würdet ihr machen - das Attribut wegschmeißen und als Where-Klausel formulieren oder es benutzen und damit die BCNF verletzen?

    Gruß,

    Amica
    Zuletzt geändert von AmicaNoctis; 17.09.2009, 21:32.
    [COLOR="DarkSlateGray"]Hast du die [COLOR="DarkSlateGray"]Grundlagen zur Fehlersuche[/color] gelesen? Hast du Code-Tags benutzt?
    Hast du als URL oder Domain-Beispiele example.com, example.net oder example.org benutzt?
    Super, danke!
    [/COLOR]

  • #2
    Zitat von AmicaNoctis Beitrag anzeigen
    [...] denn die Where-Klausel würde über 3 Zeilen gehen und verlangsamt die Abfrage auch maßgeblich.
    Wie maßgeblich?

    Sind für die einzelnen dabei betroffenen Spalten Indexe vergeben?

    Was würdet ihr machen - das Attribut wegschmeißen und als Where-Klausel formulieren oder es benutzen und damit die BCNF verletzen?
    Prinziell guten Gewissens letzteres - wenn mir die Umstände entsprechend gravierend erschienen. D.h., in einem komplexeren Fall schon, aber der hier vorliegende scheint mir noch nicht so "tragisch", dass eine Ermittlung über die WHERE-Klausel sich derart schmerzbar bei der Performance bemerkbar machen dürfte (bzw. müsste).
    I don't believe in rebirth. Actually, I never did in my whole lives.

    Kommentar


    • #3
      Zitat von wahsaga Beitrag anzeigen
      Wie maßgeblich?

      Sind für die einzelnen dabei betroffenen Spalten Indexe vergeben?
      Mit der komplexen Where-Klausel dauert es doppelt so lange wie mit "where is_distinguishable = true". Dabei ist es unerheblich, ob die Spalten indiziert sind oder nicht, da es ja nicht um konkrete Werte geht, sondern um die Tatsache, ob der Wert NULL bzw. leer ist.

      (Ich hab es trotzdem erst ohne Indizes probiert und dann welche angelegt und nochmal getestet, gleiches Ergebnis.)

      Amica
      [COLOR="DarkSlateGray"]Hast du die [COLOR="DarkSlateGray"]Grundlagen zur Fehlersuche[/color] gelesen? Hast du Code-Tags benutzt?
      Hast du als URL oder Domain-Beispiele example.com, example.net oder example.org benutzt?
      Super, danke!
      [/COLOR]

      Kommentar


      • #4
        Zitat von AmicaNoctis Beitrag anzeigen
        Mit der komplexen Where-Klausel dauert es doppelt so lange wie mit "where is_distinguishable = true".
        Naja, das doppelte von ein paar Millisekunden sind immer noch ein paar Millisekunden. Der Aufwand das Feld zu pflegen ist bestimmt größer wie diese eine Queryoptimierung.
        Wieso ist form_of_address ein FKey und kein ENUM? Vielleicht bringt der Join weniger ja schon etwas mehr...

        Kommentar


        • #5
          Zitat von PHP-Desaster Beitrag anzeigen
          Naja, das doppelte von ein paar Millisekunden sind immer noch ein paar Millisekunden. Der Aufwand das Feld zu pflegen ist bestimmt größer wie diese eine Queryoptimierung.
          Da hast du recht, also mach ich es normalisiert.

          Zitat von PHP-Desaster Beitrag anzeigen
          Wieso ist form_of_address ein FKey und kein ENUM?
          Weil ENUMs nicht internationalisierbar sind.

          Zitat von PHP-Desaster Beitrag anzeigen
          Vielleicht bringt der Join weniger ja schon etwas mehr...
          Das wird nicht gejoint. Die Anreden lädt der Client nur einmal und zeigt sie auf Basis des Schlüsselwertes mit einem speziellen ColumnRenderer an.

          Danke für die Entscheidungshilfe!

          Gruß,

          Amica
          Zuletzt geändert von AmicaNoctis; 17.09.2009, 23:50.
          [COLOR="DarkSlateGray"]Hast du die [COLOR="DarkSlateGray"]Grundlagen zur Fehlersuche[/color] gelesen? Hast du Code-Tags benutzt?
          Hast du als URL oder Domain-Beispiele example.com, example.net oder example.org benutzt?
          Super, danke!
          [/COLOR]

          Kommentar


          • #6
            Zitat von AmicaNoctis Beitrag anzeigen
            Wieso ist form_of_address ein FKey und kein ENUM?
            Weil ENUMs nicht internationalisierbar sind.
            Doch - wenn man den nummerischen Wert zum Lookup in einer Tabelle nutzt, in der die lokalisierten Bezeichner abgelegt sind ;-)
            I don't believe in rebirth. Actually, I never did in my whole lives.

            Kommentar


            • #7
              Zitat von wahsaga Beitrag anzeigen
              Doch - wenn man den nummerischen Wert zum Lookup in einer Tabelle nutzt, in der die lokalisierten Bezeichner abgelegt sind ;-)
              Und sowas nennt man dann Fremdschlüssel

              OffTopic:
              Zitat von wahsaga Beitrag anzeigen
              in der die lokalisierten Bezeichner abgelegt sind
              Nennt man das im Deutschen auch "lokalisiert"? Lokalisieren (Ort bestimmen) ist doch engl. locate und engl. localize (regional anpassen) ist das was ich als Internationalisierung kenne. Ist irgendein Sprachexperte da, um das zu klären?
              Zuletzt geändert von AmicaNoctis; 18.09.2009, 00:22.
              [COLOR="DarkSlateGray"]Hast du die [COLOR="DarkSlateGray"]Grundlagen zur Fehlersuche[/color] gelesen? Hast du Code-Tags benutzt?
              Hast du als URL oder Domain-Beispiele example.com, example.net oder example.org benutzt?
              Super, danke!
              [/COLOR]

              Kommentar


              • #8
                Zitat von AmicaNoctis Beitrag anzeigen
                Weil ENUMs nicht internationalisierbar sind.
                Ok, das ist ein Argument. Aber wie sieht denn deine form_of_address-Tabelle aus? Wenn ich mich nicht irre hast du doch immer die Anrede Herr/Frau, oder sehe ich das falsch? Berücksichtigst du auch sowas umgangssprachliches wie "Miss" im Englischen?
                Weil sonst zählt das Argument nicht. Ganz im Gegenteil, das wäre für mich sogar ein Gegenargument und die Übersetzung der ENUM-Werte Herr/Frau findet in der Applikation statt. Bin da aber nicht der Profi, klär mich doch mal auf

                Kommentar


                • #9
                  Also das sieht mir doch sehr nach einer Reise nach Absurdistan aus.

                  Wenn ich das ENUM { Herr, Frau, Fräulein } in der Applikation übersetze, brauche ich eine wieder eine Tabelle. Woher kommt die? Richtig - aus der DB. Der Lookup erfolgt dabei dann über den ENUM-Wert, was hab ich dann? Richtig - nen Fremdschlüssel, nur dass der dann nicht einfach tinyint ist, sondern ENUM. Es läuft trotzdem immer auf einen Fremdschlüssel hinaus.

                  Daher die Frage: Wovon genau willst du mich jetzt überzeugen?

                  Gruß,

                  Amica
                  [COLOR="DarkSlateGray"]Hast du die [COLOR="DarkSlateGray"]Grundlagen zur Fehlersuche[/color] gelesen? Hast du Code-Tags benutzt?
                  Hast du als URL oder Domain-Beispiele example.com, example.net oder example.org benutzt?
                  Super, danke!
                  [/COLOR]

                  Kommentar


                  • #10
                    Zitat von AmicaNoctis Beitrag anzeigen
                    Woher kommt die? Richtig - aus der DB. Der Lookup erfolgt dabei dann über den ENUM-Wert, was hab ich dann? Richtig - nen Fremdschlüssel, nur dass der dann nicht einfach tinyint ist, sondern ENUM. Es läuft trotzdem immer auf einen Fremdschlüssel hinaus.
                    Wenn du deine Übersetzungstexte in der Datenbank hast, kannst du es so machen. Aber du unterstützt damit ja nur eine Sprache oder sehe ich das falsch? Ich kann dir ehrlich gesagt nicht so ganz folgen wieso ich einen Verweis auf eine Extratabelle benötige. Nimm einen ENUM (Frau, Herr) und die Werte übersetzt du im Locale-Adapter, zum Beispiel mit einer MessageID "Anrede".ENUM_VALUE . Wo die Übersetzung letztenendes her kommt, ob da eine Datenbank oder ein gettext hintersteckt, sollte dir egal sein.
                    Zuletzt geändert von PHP-Desaster; 18.09.2009, 02:07.

                    Kommentar


                    • #11
                      Zitat von PHP-Desaster Beitrag anzeigen
                      Wenn du deine Übersetzungstexte in der Datenbank hast, kannst du es so machen. Aber du unterstützt damit ja nur eine Sprache oder sehe ich das falsch?
                      Wenn ich nur eine Sprache unterstützen würde, könnte man kaum von Übersetzungstexten sprechen.

                      Zitat von PHP-Desaster Beitrag anzeigen
                      Ich kann dir ehrlich gesagt nicht so ganz folgen wieso ich einen Verweis auf eine Extratabelle benötige.
                      Würde ein komplettes Beispiel helfen?

                      Code:
                      [SIZE="2"]form_of_address
                      ---------------
                      id
                      text_fkey => text.id
                      
                      
                      text
                      ----
                      id
                      
                      
                      i18n_text
                      ---------
                      id
                      language_fkey => language.id
                      text_fkey     => text.id
                      content
                      
                      
                      language
                      --------
                      id
                      iso_639_1_code
                      iso_639_2_code
                      iso_639_name
                      native_name_fkey => text.id
                      
                      
                      select f.id, i.content, l.iso_639_name
                      from form_of_address as f
                      join i18n_text as i on i.text_fkey = f.text_fkey
                      join language as l on l.id = i.language_fkey
                      where l.iso_639_2_code = 'swa' or l.iso_639_2_code = 'deu'
                      order by f.id, l.iso_639_2_code
                      
                      +----+----------+--------------+
                      | id | content  | iso_639_name |
                      +----+----------+--------------+
                      |  1 | Herr     | German       |
                      |  1 | bwana    | Swahili      |
                      |  2 | Frau     | German       |
                      |  2 | bibi     | Swahili      |
                      |  3 | Fräulein | German       |
                      |  3 | bibi     | Swahili      |
                      +----+----------+--------------+
                      [/SIZE]

                      Zitat von PHP-Desaster Beitrag anzeigen
                      Nimm einen ENUM (Frau, Herr) und die Werte übersetzt du im Locale-Adapter, zum Beispiel mit einer MessageID "Anrede".ENUM_VALUE . Wo die Übersetzung letztenendes her kommt, ob da eine Datenbank oder ein gettext hintersteckt, sollte dir egal sein.
                      Warum sollte ich denn jetzt wieder alles über den Haufen werfen? Das ist ein konsequenter, absolut relational korrekter Ansatz, den ich seit Jahren erfolgreich verwende, wenn es um multilinguale Projekte geht. Meine Frage war ja eigentlich eine ganz andere und ich verstehe immer noch nicht, warum jetzt alle auf der Anrede rumhacken.

                      Gruß,

                      Amica
                      Zuletzt geändert von AmicaNoctis; 18.09.2009, 12:48.
                      [COLOR="DarkSlateGray"]Hast du die [COLOR="DarkSlateGray"]Grundlagen zur Fehlersuche[/color] gelesen? Hast du Code-Tags benutzt?
                      Hast du als URL oder Domain-Beispiele example.com, example.net oder example.org benutzt?
                      Super, danke!
                      [/COLOR]

                      Kommentar


                      • #12
                        Zitat von AmicaNoctis Beitrag anzeigen
                        Würde ein komplettes Beispiel helfen?
                        Ja, vielen Dank, das hat sogar sehr geholfen. Werde dann jetzt auch nicht mehr drauf herumhacken

                        Kommentar


                        • #13
                          Zitat von PHP-Desaster Beitrag anzeigen
                          Ja, vielen Dank, das hat sogar sehr geholfen. Werde dann jetzt auch nicht mehr drauf herumhacken
                          Fein, na dann danke ebenfalls
                          [COLOR="DarkSlateGray"]Hast du die [COLOR="DarkSlateGray"]Grundlagen zur Fehlersuche[/color] gelesen? Hast du Code-Tags benutzt?
                          Hast du als URL oder Domain-Beispiele example.com, example.net oder example.org benutzt?
                          Super, danke!
                          [/COLOR]

                          Kommentar


                          • #14
                            Zitat von AmicaNoctis Beitrag anzeigen
                            Nennt man das im Deutschen auch "lokalisiert"? Lokalisieren (Ort bestimmen) ist doch engl. locate und engl. localize (regional anpassen) ist das was ich als Internationalisierung kenne. Ist irgendein Sprachexperte da, um das zu klären?
                            Meines Wissens hast Du diesbezüglich vollkommen Recht.

                            1. Ja, ich habe die entsprechenden Einträge im Manual gelesen. Google habe ich auch benutzt. Das mache ich immer zuerst, wenn ich eine Frage habe, denn ich habe zu Glück das selbstständige Denken gelernt, sonst würde ich nicht fragen
                            2. Ja, ich besitze den erstzunehmenden Ehrgeiz, die Dinge, nach denen ich frage, auch zu begreifen und/oder begreifen zu lernen, sonst würde ich nicht fragen

                            Kommentar

                            Lädt...
                            X