2010-07-28 13 views
5

Bret Taylor hanno discusso lo SchemaLess design in questo post del blog: http://bret.appspot.com/entry/how-friendfeed-uses-mysqlDomande su di FriendFeed MySql SchemaLess design

Sembra che memorizzati gli oggetti di classe diversa in una sola table.Then costruire più tabelle di indice.

la mia domanda è che come costruire indice su una classe.

ad esempio, il blog di un utente è {id, userid, title, body}. Il tweet di un utente è {id, userid, tweet}.

Se voglio creare un indice per i blog degli utenti, come posso fare?

+0

si consiglia per guardare [database dei documenti] (http://en.wikipedia.org/wiki/Document-oriented_database). Questi ti consentono anche di archiviare interi documenti, proprio come fa FriendFeed, ma il database si occupa di tutte le indicizzazioni per te. –

risposta

10

È molto semplice, forse più semplice di quanto ci si aspetti.

Quando si archivia un'entità blog, si intende inserire nella tabella delle entità principali, ovviamente. Un blog è simile al seguente:

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: ... }' 
); 

Si inserisce anche in una tabella di indice separata per ciascun tipo logico di attributo. Usando il tuo esempio, l'ID utente per un blog non è lo stesso di un ID utente per un tweet. Dal momento che appena inserito un blog, è quindi inserire nella tabella indice (s) per l'attributo blog (s):

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'); 

Non inserire in tutte le tabelle di indice Tweet, perché hai appena creato un blog, non un tweet .

Conoscete tutte le righe nei blog di riferimento blog_userid, perché è così che li avete inseriti. Così si può cercare per i blog di un dato utente:

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

Re tuo commento:

Sì, è possibile aggiungere colonne reali alla tabella enti per gli attributi che si sa si applicano a tutti i contenuti tipi. Per esempio:

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 
); 

Le colonne per entity_type e creation_date permetterebbe di strisciare le entità in ordine cronologico (o invertire ordine cronologico) e sapere quale serie di tabelle di indice corrisponde al tipo di entità di una data riga.

+0

Ma accroding all'articolo. a volte possono eseguire la scansione della tabella delle entità per creare un nuovo indice o modificare il vecchio indice. Penso che possa essere possibile aggiungere un nuovo "valore" di valore-chiave: "blog" o "tipo": "tweet" nel blob.C'è qualche suggerimento migliore? – user404017

0

Non memorizzano oggetti di classi diverse nella stessa tabella. La tabella delle "entità" a cui si riferiscono è utilizzata per memorizzare solo un tipo di entità.

Per esempio, un soggetto tipico in FriendFeed potrebbe assomigliare a questo:

"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, 

Per comprendere l'attuazione meglio, hanno uno sguardo al Nell'esempio qui riportato: https://github.com/jamesgolick/friendly#readme

+0

Credo che sia esattamente quello che fanno (memorizzano oggetti di diversi tipi nella stessa tabella). Se si guarda il link dal post originale, si dice "le nostre entità sono memorizzate in una tabella simile a questa ... TABLE entity". Il contenuto dell'entità che fornisci un esempio è contenuto nel campo del corpo della tabella delle entità. Penso che questo sia il punto centrale del design, mi manchi qualcosa? – riley

+0

Sì, ti manca qualcosa. Il suo unico tipo di entità. Usano il design senza schema in modo che possano aggiungere e rimuovere colonne senza bloccare la tabella. Tutte le entità sono le stesse con l'eccezione delle entità esistenti prima che un campo fosse aggiunto non hanno quel campo particolare nel loro JSON. –