2009-06-05 6 views
2

Ich bin ein ziemlich neuer Entwickler MySQL und fange an einem Projekt, das ich mit ein bisschen Erstberatung tun könnte auf ...MySQL Datenbank-Design Optimiert für Datenbeschaffung in PHP

Ich erstelle eine Datenbank, wird in erster Linie eine bestimmte Anzahl von Items (zwischen 1-5k) und etwa 40 booleschen Variablen, die mit jedem verknüpft sind. Benutzer geben dann ihre Auswahl dieser 40 Werte ein, und es ist die Aufgabe des Systems, die "besten" übereinstimmenden Elemente zu bestimmen. Dies können Elemente sein, die mit allen 40 Variablen übereinstimmen, oder, falls keine vorhanden sind, diejenigen, die 39 usw. entsprechen.

Also, ein paar Fragen, wenn jemand Zeit hat!

  1. Aus meiner Erfahrung mit MySQL gibt es keinen signifikanten Geschwindigkeitsvorteil bei der Aufteilung von Daten in separate Tabellen für eine Datenbank dieser Größe. Die Gemeinkosten für mehr Tabellen sind einfach zu groß, um einen brauchbaren Unterschied für die Gesamtleistung zu machen. Daher würde ich vorschlagen, einfach eine große Tabelle mit 40 Spalten und bis zu 5000 Zeilen zu erstellen, um alle Informationen zu speichern (Tabellensperren sind kein Problem, da alle Abfragen SELECT sind). Passt das zum Denken und zur Erfahrung anderer?
  2. Was wäre der effizienteste Weg, das beste Spiel zurückzugeben? Ist das überhaupt möglich durch Datenbankstruktur und SQL-Befehle allein oder werde ich einfach das gesamte Array nach PHP zurückgeben und eine Form der heuristischen Funktion ausführen, um dort die besten Übereinstimmungen zu ermitteln?

Danke für Ihre Zeit & Hilfe!

Antwort

3

Ein einzelner Tisch ist sicherlich richtig. Sie können bis zu 64 boolesche Variablen in einer einzelnen Spalte BIGINT als "Maske" mit einem Bool pro Bit speichern und die Übereinstimmung extrem schnell berechnen, wie BIT_COUNT(~(the_column^user_preferences)), die zählt, wie viele Bits zwischen der Spalte und der Maske des Benutzers übereinstimmen Voreinstellungen (sollte PHP Ihnen Probleme bei der Manipulation von 64-Bit-Ganzzahlen geben, können Sie zwei Spalten mit je 32 Bit verwenden, die Summe der beiden Bit-Zahlen ist immer noch sehr schnell).

0

Ich würde zwei Tabellen verwenden. Eine für die Elemente und eine für die booleschen Flags, die mit einem Element übereinstimmen. Machen Sie nur einen Eintrag in der Tabelle "Flags" für Übereinstimmungen für einen Artikel. Dann, um die Anzahl der Übereinstimmungen für ein Element zu erhalten, wäre einfach eine Zählung der Datensätze in der 'Flags' Tabelle, die die ItemId aus der 'Items' Tabelle entsprechen.

+0

Wenn Sie diese Route gehen, können Sie auch "negative Übereinstimmungen" mit einem äußeren Join und "IS NULL" in den 'WHERE' -Klauseln zählen; Trotzdem denke ich, dass es im Vergleich zu dem von mir vorgeschlagenen BIT_COUNT etwas umständlich ist. –

0

Ich denke nicht, dass das die beste Methode ist, um diese Art von Informationen zu speichern. Es kann visuell gut aussehen, aber wenn all Ihre Speicherung boolesche Werte ist, würde ich zwei Tabellen und eine Verknüpfungstabelle mit Einträgen für jeden passenden wahren Wert erstellen.

Hier gibt es keinen Overhead, da MySQL lieber Zeilen statt Spalten sucht. Die Funktion count() wird dann nützlich sein.

Ich bin mir ziemlich sicher, wenn es keine Übereinstimmung findet, müssen Sie zu PHP zurückkehren, um die Suche auszuführen, um eine Übereinstimmung für 39 und so weiter zu finden. Eine rekursive Funktion wäre ein guter Weg, dies zu tun.

z.B.

Tabelle xOption id, name

Tabelle yOption id, name

Tabelle xOption_yOption xOption_id, yOption_id

Die andere gute daran ist, Sie leicht mehr X- oder Y-Optionen hinzufügen später zu Ihrem Grid und Sie könnten weitere Details zu den Optionen speichern.

Vergessen Sie nicht, Indizes auch zu verwenden.

Verwandte Themen