Frage

Ich arbeite an einem Upgrade für eine vorhandene Datenbank, die entworfen wurde, ohne dass der Code der Entwurf wird in Betracht gezogen zu implementieren. Jetzt habe ich trifft das Datenbank-Design in Code eine Mauer bei der Umsetzung. Ich bin sicher, ob es ein Problem mit dem Design der Datenbank oder wenn ich einfach nicht die richtige Lösung zu sehen, wie man was getan werden muss.

Die grundlegende Logik schreibt vor, wie folgt vor:

  1. Der Zugriff auf das Online-Training über die Sitzplätze. Benutzer können mehrere Sitze haben.
  2. Sitze werden von Unternehmen gekauft und haben eine viele-zu-viele-Beziehung mit Produkte.
  3. Ein Produkt hat eine viele-zu-viele-Beziehung mit Modulen.
  4. A-Modul hat eine viele-zu-viele-Beziehung mit Lektionen.
  5. Die Lektionen sind die Endanwender für ihre Ausbildung zugreifen zu können.
  6. Um das Wasser schlammig, für einen oder anderen Grund einige Nutzer haben mehrere Sitze, die die gleichen Produkte enthalten.
  7. Zertifizierung erfolgt auf einer pro Produkt Basis, nicht pro Sitzbasis.
  8. Nutzer haben eine viele-zu-viele-Beziehung mit Lektionen, die ihren aktuellen Status speichert oder für den Unterricht punkten.
  9. Benutzer für ein Produkt zertifizieren, wenn sie alle Lektionen in allen Modulen für das Produkt abzuschließen.
  10. Es ist auch von Bedeutung zu wissen, wenn alle Lektionen für ein bestimmtes Modul von einem Benutzer abgeschlossen werden.
  11. Einige Sitze werden für die Rezertifizierung Bedeutung sein, dass Benutzer, die zuvor für ein Produkt zertifiziert können eine Rezertifizierungsprüfung anmelden und nehmen.
  12. Durch Regel 11 können die Benutzer und mehrere Zertifizierungs Datensätze haben.
  13. Edit: Wenn ein Benutzer eine Lektion (Scores besser als 80%) abgeschlossen ist dann der Nutzer hat (entsprechend der aktuellen Geschäftslogik) komplettierten die Lektion für alle Produkte und alle Sitze, die die Lektion enthalten.

Das Problem, das ich laufe immer in dem aktuellen Design und die Business-Logik, wie ich mehr oder weniger habe beschrieben ist es, dass ich nicht einen Weg, um effektiv zu binden, ob ein Benutzer für ein bestimmtes Produkt und Sitz zertifiziert finden vs, wenn sie nicht haben. Ich behalte das Schlagen Tücken versuchen, unter denen zu etablieren, welche Produkte Sitze sind für den Benutzer zertifiziert und welche nicht. Ein Teil des Problems ist, weil, wenn sie zur Zeit für mehr von dem gleichen Produkt unter verschiedenen Sitzen registriert sind, dann muß ich nur einmal die Produkte zählt.

Im Folgenden finden Sie eine Kopie des Teils des Schemas, das beteiligt ist. Alle Vorschläge, wie das Design zu verbessern oder den Verein in Code ziehen würden geschätzt. Für den Fall, es darauf ankommt, ist diese Seite auf dem LAMPP Stapel gebaut.

Sie können den relevanten Teil des Datenbankschemas sehen hier: http://lpsoftware.com/problem_db_structure.png

War es hilfreich?

Lösung

Was Sie suchen relationale Division Nicht direkt in SQL implementiert, aber es kann getan werden. Google-Suche nach anderen Beispielen.

Andere Tipps

Nach einem kurzen Blick auf das Schema denke ich, eines der Dinge, die Sie tun können, ist eine ‚to_be_certified‘ Tabelle erstellen. Füllen Sie es mit user_id, product_id und seat_id, wenn ein Produkt mit einem Sitz zugeordnet ist (wenn product_seat_rtab bevölkert ist).

Auf einen Datensatz der certification_rtab Tabelle hinzufügen, löschen Sie den entsprechenden Eintrag in der ‚to_be_certified‘ Tisch. Dies gibt Ihnen einen einfachen Zugang zu allen Produkten, die für einen Benutzer und die, die zertifiziert sind, die es nicht sind.

Um loszuwerden doppelten product_ids zu erhalten, können Sie Gruppe von product_id.

Sie müssen Änderungen an der lessonstatus_rtab Tabelle machen:

CREATE TABLE lessonstatus_rtab (
  user_id    INT NOT NULL,
  seat_id    INT NOT NULL,
  lesson_id  INT NOT NULL REFERENCES lesson_rtab,
  accessdate TIMESTAMP,
  score      NUMERIC(5,2) NOT NULL DEFAULT 0,
  PRIMARY KEY (user_id, seat_id, lesson_id),
  FOREIGN KEY (user_id, seat_id) REFERENCES user_seat_rtab (user_id, seat_id)
);

Dann können Sie für jedes Produkt abfragen, die ein Benutzer für einen Sitz hat, ist er zertifiziert? Dies setzt voraus, dass die Anzahl der Lektionen, die er geschossen hat, sagen wir, 50% oder höher ist die gleiche wie die Anzahl der Unterrichtsstunden in allen Modulen für das Produkt.

SELECT p.name, us.user_id, us.seat_id, COUNT(l.id) = COUNT(lu.lesson_id) AS is_certified
FROM user_seat_rtab AS us
 JOIN seat_rtab AS s ON (s.id = us.seat_id)
 JOIN product_seat_rtab AS ps ON (ps.seat_id = s.id)
 JOIN product_rtab AS p ON (p.id = ps.product_id)
 JOIN product_module_rtab AS pm ON (pm.product_id = p.id)
 JOIN module_rtab AS m ON (m.id = pm.module_id)
 JOIN module_lesson_rtab AS ml ON (ml.module_id = m.id)
 JOIN lesson_rtab AS l ON (l.id = ml.lesson_id)
 LEFT OUTER JOIN lessonstatus_rtab AS lu 
   ON (lu.lesson_id = l.id AND lu.user_id = us.user_id 
     AND lu.seat_id = us.seat_id AND lu.score > 0.50)
GROUP BY p.id, us.user_id, us.seat_id;

UPDATE:

Ich habe angesichts dieser Frage weiter und habe überlegt, ob es Dinge würde es ermöglichen, besser zu arbeiten, einfach die user_seat_rtab Tabelle zu entfernen und dann die entsprechende certification_rtab Tabelle verwenden (wahrscheinlich umbenannt) alle Informationen über den Status eines Benutzers Sitz zu halten . Auf diese Weise gibt es eine direkte Beziehung zwischen einem Benutzer festgelegt, deren Sitz, jedes Produkt im Sitz, und ob der Nutzer hat für das jeweilige Produkt zertifiziert und Seat.

So würde ich die folgenden Änderungen an das Schema mit der Frage gepostet gelten:

DROP TABLE user_seat_rtab;
RENAME TABLE certification_rtab TO something_different;

Eine Alternative zur Weiterentwicklung dieser neuen Struktur zu normalisieren würde, so etwas zu tun:

ALTER TABLE user_seat_rtab 
    DROP PRIMARY KEY;
    ADD COLUMN product_id int(10) unsigned NOT NULL;
    ADD CONSTRAINT pk_user_seat_product PRIMARY KEY (user_id, seat_id, product_id);
    ADD CONSTRAINT fk_product_user_seat FOREIGN KEY (product_id) REFERENCES product_rtab(id) ON DELETE RESTRICT;

Ich bin nicht wirklich sicher, ob dies das Problem lösen würde oder ob es nur die Art des Problems leicht ändern, während der Einführung neuer. Also, hat jemand irgendwelche andere Kritik oder Anregungen?

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top