2010-07-28 5 views
5

Bret Taylor diskutiert die SchemaLess Entwurf in diesem Blog-Eintrag: http://bret.appspot.com/entry/how-friendfeed-uses-mysqlFragen zu Friend der MySql SchemaLess Entwurf

Es sieht aus wie sie mehr Indextabellen andere Klasse Objekte in nur einem table.Then gespeichert bauen.

meine Frage ist, wie man Index auf einer Klasse zu bauen.

Beispiel: Ein Blog eines Benutzers ist {ID, Benutzerkennung, Titel, Nachricht}. Der Tweet eines Benutzers lautet {id, userid, tweet}.

Wenn ich einen Index für Benutzerblogs erstellen möchte, wie kann ich tun?

+0

Sie möchten auf [Dokumentendatenbanken] (http://en.wikipedia.org/wiki/Document-oriented_database). Diese erlauben es Ihnen, auch ganze Dokumente zu speichern, genau wie FriendFeed, aber die Datenbank kümmert sich um die gesamte Indizierung für Sie. –

Antwort

10

Es ist sehr einfach - vielleicht einfacher als Sie erwarten.

Wenn Sie eine Blog-Entität speichern, fügen Sie sie natürlich in die Tabelle der Haupteinheiten ein. Ein Blog geht so:

CREATE TABLE entities (
    id INT AUTO_INCREMENT PRIMARY KEY, 
    entity_json TEXT NOT NULL 
); 

INSERT INTO entities (id, entity_json) VALUES (DEFAULT, 
    '{userid: 8675309, 
     post_date: "2010-07-27", 
     title: "MySQL is NoSQL", 
     body: ... }' 
); 

Sie fügen auch in eine separate Indextabelle für jeden logischen Typ des Attributs ein. In Ihrem Beispiel ist die Benutzer-ID für ein Blog nicht identisch mit einer Benutzer-ID für einen Tweet. Da Sie nur ein Blog eingefügt, legen Sie dann in Indextabelle (e) für Blog-Attribut (e):

CREATE TABLE blog_userid (
    id INT NOT NULL PRIMARY KEY, 
    userid BIGINT UNSIGNED, 
    KEY (userid, id) 
); 

INSERT INTO blog_userid (id, userid) VALUES (LAST_INSERT_ID(), 8675309); 

CREATE TABLE blog_date (
    id INT NOT NULL PRIMARY KEY, 
    post_date DATETIME UNSIGNED, 
    KEY (post_date, id) 
); 

INSERT INTO blog_date (id, post_date) VALUES (LAST_INSERT_ID(), '2010-07-27'); 

nicht in irgendwelche tweet Index-Tabellen einfügen Sie, weil Sie nur ein Blog erstellt, nicht ein Tweet .

Sie kennen alle Zeilen in blog_userid Referenz-Blogs, denn so haben Sie sie eingefügt. So können Sie für Blogs von einem bestimmten Benutzer suchen:

SELECT e.* 
FROM blog_userid u JOIN entities e ON u.id = e.id 
WHERE u.userid = 86765309; 

Re Ihr Kommentar:

Ja, könnten Sie echte Spalten an den Einheiten Tabelle hinzufügen für alle Attribute, die Sie auf alle Inhalte anwenden kennen Arten. Zum Beispiel:

CREATE TABLE entities (
    id INT AUTO_INCREMENT PRIMARY KEY, 
    entity_type INT NOT NULL, 
    creation_date TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, 
    entity_json TEXT NOT NULL 
); 

Die Spalten für ENTITY_TYPE und creation_date Sie erlauben würde, die Entitäten in chronologischer Reihenfolge (oder umgekehrt chronologische Reihenfolge) und wissen, welche Gruppe von Indextabellen entsprechen den Entitätstyp einer bestimmte Zeile zu kriechen.

+0

Aber accroding zu dem Artikel. Manchmal können sie die Entitätstabelle durchsuchen, um einen neuen Index zu erstellen oder den alten Index zu ändern. Ich denke vielleicht kann man einen neuen Schlüssel-Wert "type" hinzufügen: "blog" oder "type": "tweet" in den Blob.Gibt es einen besseren Vorschlag? – user404017

0

Sie speichern keine Objekte verschiedener Klassen in derselben Tabelle. Die Entity-Tabelle, auf die sie sich beziehen, wird verwendet, um nur eine Art von Entitäten zu speichern.

Zum Beispiel kann eine typische Einheit in Friend könnte wie folgt aussehen:

"id": "71f0c4d2291844cca2df6f486e96e37c", 
"user_id": "f48b0440ca0c4f66991c4d5f6a078eaf", 
"feed_id": "f48b0440ca0c4f66991c4d5f6a078eaf", 
"title": "We just launched a new backend system for FriendFeed!", 
"link": "http://friendfeed.com/e/71f0c4d2-2918-44cc-a2df-6f486e96e37c", 
"published": 1235697046, 
"updated": 1235697046, 

Um die Umsetzung besser zu verstehen, haben einen Blick auf das Beispiel hier gegeben: https://github.com/jamesgolick/friendly#readme

+0

Ich glaube, das ist genau das, was sie tun (Objekte verschiedener Typen in der gleichen Tabelle speichern). Wenn Sie sich den Link vom ursprünglichen Post ansehen, heißt es: "Unsere Entitäten sind in einer Tabelle gespeichert, die wie folgt aussieht .... TABLE-Entitäten". Der Entitätsinhalt, den Sie als Beispiel angeben, ist im Feld body der Entitätentabelle enthalten. Ich denke, das ist der springende Punkt des Designs, vermisse ich etwas? – riley

+0

Ja, du verpasst etwas. Es ist eine Art von Entität. Sie verwenden das schemafreie Design, sodass sie Spalten hinzufügen und entfernen können, ohne die Tabelle zu sperren. Alle Entitäten sind identisch mit Ausnahme von Entitäten, die vor dem Hinzufügen eines Felds vorhanden waren. Dieses bestimmte Feld muss nicht in ihrem JSON enthalten sein. –