2009-07-11 3 views
24

Kommen aus einer relationalen Welt Dinge sind offensichtlich sehr unterschiedlich mit dem Azure Table Speicher. Die erste wichtige Sache, auf die ich gestoßen bin, ist, wie Many-to-Many-Beziehungen richtig gespeichert werden.Wie kann ich Datenbeziehungen mit Microsoft Azure Table Storage ordnungsgemäß speichern?

Zum Beispiel kann ich ein System haben, das Benutzer und Bücher verfolgt, die sie besitzen. Ich habe einen anderen Beitrag hier auf SO gefunden, der vorgeschlagen hat, eine String-Eigenschaft auf dem Benutzer zu haben, die im Grunde eine Liste der Buch-IDs speichert, die der Benutzer besaß. Während ich verstehe, dass dies manchmal eine akzeptierte Möglichkeit zum Speichern von Daten ist, besteht das Problem darin, dass Azure nur 64 KB Daten in einem String speichern kann. Das legt definitiv eine Grenze fest, wie viele Bücher ein Benutzer möglicherweise besitzen könnte.

Eine andere mögliche Lösung ist, doppelte Daten zu haben. Ich habe vielleicht eine Tabelle, die alle bekannten Bücher im System speichert. Aber wenn ein Benutzer mit einem Buch verknüpft werden muss, kopiere ich die Buchdaten in eine andere Tabelle namens OwnedBooks, die im Wesentlichen genauso wie die Buch-Tabelle ist, außer dass sie auch eine OwnedByUserID-Eigenschaft besitzt.

Gibt es andere mögliche Lösungen?

Neben diesem Problem hat jemand gute Vorschläge für andere Muster und Praktiken bei der Verwendung von Azure-Tabellenspeicher?

Antwort

16

Es gibt eine Reihe von Lösungen für dieses - alle mit Nachteilen natürlich :-)

  1. eine einfache Zuordnungstabelle verwenden, wie Sie in einem RDBMS würde. Jede Zeile enthält einen Buchschlüssel und einen Benutzerschlüssel.

    Um dann alle Bücher für einen Benutzer zu finden, wählen Sie die Buchschlüssel in der Mapping-Tabelle und dann für jeden dieser Schlüssel die Buch-Entität aus der Tabelle Bücher. Sie könnten die Buchabrufvorgänge mit Async-Abruf parallel durchführen, aber diese Lösung skaliert offensichtlich nicht.

  2. Verwenden Sie eine Zuordnungstabelle wie oben, aber schließen Sie alle Buchdaten ein, die Sie auch in der Zuordnungstabelle benötigen. Dies ist die denormalisierte oder "duplizierte Daten" -Lösung, die Sie bereits mit Ihrer OwnedBooks-Tabelle vorgeschlagen haben.

    Der Hauptnachteil dieser Methode ist, dass, wenn Sie eine der Buchdaten aktualisieren müssen, Sie möglicherweise viele Entitäten aktualisieren werden - und da sie in einer separaten Tabelle zu dem Buch selbst leben, wird es nicht möglich sein in einer einzigen Transaktion/Batch abgeschlossen werden (und ich würde mir vorstellen, dass Sie die Benutzeridentität trotzdem als Partitionsschlüssel in der Zuordnungstabelle verwenden würden, was bereits eine einzelne Stapelaktualisierung in dieser Tabelle ausschließt).

  3. Speichern Sie die Book-Keys in einer einzigen Eigenschaft des Benutzers. Auch hier haben Sie diese Methode bereits vorgeschlagen.

    Dies wäre eigentlich nicht so schlimm, wenn es nicht für die Tatsache, dass Azure derzeit "enthält" Typ Abfragen nicht unterstützt - dh Sie können nicht auf einem Teilstring suchen, also wenn Sie jemals wollten herauszufinden, welche Benutzer ein bestimmtes Buch besaß, wäre dies unmöglich.Interessanterweise unterstützt Google App Engine dies in ihrem Speichersystem ziemlich transparent - und indexiert die Liste auch für Sie. In jedem Fall müssen Sie die Daten jedes Buchs auch mit dieser Methode abrufen.

  4. Verwenden Sie die "schemalose" Art des Azure-Tabellenspeichers, um zugeordnete Buchschlüssel als einzelne Eigenschaften zu speichern. Zum Beispiel kann ein Benutzer Entität wie folgt aussehen:

    { Name: "User1", Book_4325: true, Book_5123: true }

    Während andere wie folgt aussehen:

    { Name: "User2", Book_5346: true, Book_8753: true, Book_6135: true }

    Dann, wenn Sie alle Benutzer finden wollte, die ein bestimmtes Buch besitzen Sie kann auswählen, wo diese bestimmte Eigenschaft wahr ist (nun, es muss nur wirklich existieren).

    Die offensichtlichen Nachteile davon sind, dass es ein wenig spröde ist, Sie müssen mit Schlüsseln in Eigenschaftsnamen herumspielen, und Sie wären nicht in der Lage, die Standardmethoden von StorageClient dafür zu verwenden - Sie müssten Ihre rollen besitzen. Außerdem unterstützt Azure nur 255 Eigenschaften für eine Entität. Alles, was gesagt wurde, ich denke, es würde ziemlich gut skalieren - obwohl ich es noch nie probiert habe.

Aus all diesen Möglichkeiten, würde ich sagen, die, die Sie mit, Option 2 gehen würden, würde das Beste sein, nur für die Tatsache, dass es derzeit von Azure unterstützt wird und Sie können in der Regel alles erreichen mit weniger Abfragen.

Sie müssen nur Ihre Use Cases hinterfragen, um zu entscheiden, wie und wann die Daten aktualisiert werden, wenn man berücksichtigt, dass atomare Transaktionen nicht im Fenster sind. Ich kann fast garantieren, dass Sie in der Lage sein werden, mit "letztendlich konsistenten" Dingen zu leben, und nur dafür verantwortlich sein müssen, dass Ihre Mapping-Tabelle nicht immer 100% aktuell ist.

Wenn es zu teuer wird, die Daten in der Mapping-Tabelle gleichzeitig mit der Primärtabelle zu aktualisieren, können Sie eine Nachricht in eine Warteschlange stellen und eine Worker-Rolle für die asynchrone Durchführung der Aktualisierungen erhalten.

+0

Fantastische Antwort, danke! – Vyrotek

+0

Die Wahl von Option 2 scheint, es wäre ziemlich billig, obwohl sein Nachteil. Da es nur $ 0,01 für jede 100 000 Transaktionen kostet. Jede Transaktion ist eine Abfrage an das Speicherrecht? Das Ändern eines Buchtitels würde also nur eine Abfrage nach sich ziehen, und dann wird jedes gefundene Element in der Tabelle aktualisiert. Aber es hängt davon ab, wie viele Daten Sie aktualisieren. Aber wenn Updates knapp sind, dann ist es in Ordnung. Ist es nicht? – starcorn

9

Sie nicht. Hier ist ein guter, vollständiger white paper (.docx-Link) zu Azure Table, der einen Abschnitt zu Best Practices enthält. Sie sollten jedoch Tabelle für nicht-relationale Eigenschaften-Taschen oder ORM-Typen verwenden. Wenn Sie relational in der Cloud möchten, sollten Sie SQL Azure Database verwenden.

Hier ist ein weiterer good article auf Schema-freien Speicher gegenüber relationalen. Es ist für eine different schema free cloud storage offering, aber die Konzepte sind die gleichen.

+3

Ich möchte nicht wirklich in der Cloud "wollen". Ich wollte herausfinden, wie die Leute diese Schlüsselspeicher-/Taschen-Datenbanken mit dem einfachen Beispiel verwenden, das ich zur Verfügung gestellt habe. Ich kann mir nicht vorstellen, dass irgendein Projekt, das Beziehungen zwischen Daten erfordert, nicht mit dieser oder ähnlichen Datenbanken verwendet werden kann/sollte. – Vyrotek

+2

+1 für das Azure Table-Whitepaper. Ein bisschen abseits von Thema, aber ich machte eine schnelle Suche im Internet nach dem Lesen dieser Antwort und ich fand diese URL zu allen Azure bezogenen White Papers, die sich in verschiedenen Kontexten als sehr nützlich erweisen könnten: http://www.microsoft.com/ windowsazure/whitepaper/ –