ci sono due parti a una chiave primaria in Cassandra:
- chiave di partizione (s)
- chiave di clustering (s)
PRIMARY KEY (partitionKey1,clusteringKey1,clusteringKey2)
o
PRIMARY KEY ((partitionKey1,partitionKey2),clusteringKey1,clusteringKey2)
La chiave di partizione determina che il nodo (s) i dati sono memorizzati su. La chiave di clusterizzazione determina l'ordine dei dati all'interno della chiave di partizione.
In CQL, la clausola ORDER BY
viene realmente utilizzata solo per in senso inverso nella direzione di ordinamento definita dell'ordine di clustering. Come per le colonne stesse, è possibile specificare solo le colonne definite (e nell'ordine esatto ... senza saltare) nella clausola CLUSTERING ORDER BY
al momento della creazione della tabella. Pertanto, non è possibile selezionare colonne arbitrarie per ordinare il set di risultati in fase di query.
Cassandra raggiunge le prestazioni utilizzando le chiavi di clustering per ordinare i dati su disco, restituendo quindi solo le righe ordinate in un'unica lettura (senza letture casuali). Ecco perché è necessario adottare un approccio di modellazione basato su query (spesso duplicando i dati in più tabelle di query) con Cassandra. Conosci le tue domande in anticipo e crea le tue tabelle per servirle.
Select * from emp order by empno;
Prima di tutto, è necessaria una clausola WHERE
. È possibile eseguire query senza di esso, se si sta lavorando con un database relazionale. Con Cassandra, dovresti fare del tuo meglio per evitare le query SELECT
non associate. Inoltre, Cassandra può applicare solo un ordinamento all'interno di una partizione, pertanto la query senza una clausola WHERE
non restituirà i dati nell'ordine desiderato, comunque.
In secondo luogo, come ho già detto, è necessario definire le chiavi di clustering. Se si desidera ordinare il set di risultati per empno
, è necessario trovare un'altra colonna da definire come chiave di partizione.Provare qualcosa di simile:
CREATE TABLE emp_by_dept (
empno text,
dept text,
name text,
PRIMARY KEY (dept,empno)
) WITH CLUSTERING ORDER BY (empno ASC);
Ora, posso interrogare i dipendenti per reparto, e saranno restituiti a me ordinate per empno
:
SELECT * FROM emp_by_dept WHERE dept='IT';
Ma per essere chiari, si non essere in grado di interrogare ogni riga della tabella e ordinarla da una singola colonna. L'unico modo per ottenere un ordine significativo nei set di risultati è la partizione dei dati in un modo che abbia senso per il tuo business case. L'esecuzione di un numero vuoto SELECT
restituirà tutte le righe (presupponendo che la query non termini il timeout durante il tentativo di interrogare ogni nodo nel cluster), ma l'ordine dei set di risultati può essere applicato solo all'interno di una partizione. Quindi devi limitare per chiave di partizione in modo che abbia senso.
Le mie scuse per l'autopromozione, ma l'anno scorso ho scritto un articolo per DataStax chiamato We Shall Have Order!, in cui mi sono indirizzato come risolvere questi tipi di problemi. Dagli una lettura e vedi se aiuta.
Edit per ulteriori domande:
Dalla tua risposta mi ha concluso 2 cose su Cassandra:
(1) Non v'è alcun modo di ottenere un set di risultati che è solo ordine da una colonna che ha stato definito come Unico.
(2) Quando definiamo un PK (partizione tasti + clustering chiave), allora i risultati saranno sempre ordine da Clustering colonne all'interno tasto qualsiasi parete fissa (bisogna limitare a un valore partizione-chiave), ciò significa che non c'è bisogno della clausola ORDER BY , dal momento che non può mai cambiare l'ordine delle righe (l'ordine in quali file sono effettivamente memorizzate), vale a dire l'ordine By è inutile.
1) Tutte le CHIAVI PRIMARIE in Cassandra sono uniche. Non c'è modo di ordinare il tuo risultato impostato dalla chiave di partizione. Nel mio esempio, ordino per empno
(dopo il partizionamento con dept). - Aaron 1 ora fa
2) Smettendo di dire che ORDER BY è inutile, dirò che il suo unico uso è quello di cambiare la direzione del tipo tra ASC e DESC.
Ho creato un indice sulla colonna "empno" della tabella "emp", non è ancora che consente ORDER BY empno. Quindi, a cosa servono gli indici? sono solo per i record di ricerca per il valore specifico della chiave dell'indice?
Non è possibile ordinare un set di risultati mediante una colonna indicizzata. Gli indici secondari sono (non uguali alle loro controparti relazionali) davvero utili solo per le query edge-case, basate su analisi. Non sono in scala, quindi la raccomandazione generale non è quella di utilizzare indici secondari.
Ok, ciò significa semplicemente che una tabella non può essere utilizzato per ottenere differenti insiemi di risultati con diverse condizioni e diversi classificare ordine.
Corretto.
Quindi, per ogni nuovo requisito, è necessario creare una nuova tabella. IT significa che se abbiamo un miliardo di righe in una tabella (ad esempio la tabella delle vendite) e abbiamo bisogno della somma delle vendite (1) Prodotto-saggio, (2) Region-wise, quindi lo duplicherò tutte quelle miliardi di righe in 2 tabelle con una in ordine di prodotto di clustering, l'altra in ordine di raggruppamento di Regione ,. e anche se abbiamo bisogno di sommare le vendite per Salesman_id, quindi costruiamo una terza tabella, di nuovo mettendo tutti quei miliardi di righe? è ragionevole?
Spetta a te decidere quanto sia ragionevole. Ma la mancanza di flessibilità delle query è un inconveniente di Cassandra. Per aggirare il problema è possibile continuare a creare tabelle di query (I.E., scambiando dischi per prestazioni). Ma se arriva a un punto in cui diventa sgraziato o difficile da gestire, allora è il momento di pensare se Cassandra è davvero la soluzione giusta.
EDIT 20160321
Hi Aaron, è detto sopra "Arresto a corto di dire che ORDER BY è inutile, dirò che il suo unico reale utilizzo è passare il tipo di ordinamento tra ASC e DESC ".
Ma ho trovato anche che non è corretto. Cassandra consente solo ORDINE nella stessa direzione definita nel calibro "CLUSTERING ORDER BY" di CREATE TABLE. Se in quella clausola definiamo ASC, consente solo l'ordine di ASC e viceversa.
Senza visualizzare un messaggio di errore, è difficile sapere cosa dirti su quello. Anche se ho sentito parlare di query con ORDER BY
in mancanza quando si hanno troppe righe memorizzate in una partizione.
ORDER BY
funziona anche un po 'strano se si specificano più colonne per ordinare per. Se ho definito due colonne di clustering, posso usare ORDER BY
sulla prima colonna indiscriminatamente. Ma non appena aggiungo la seconda colonna alla clausola ORDER BY
, la mia query funziona solo se si specifica entrambe le direzioni di ordinamento uguali (come la definizione CLUSTERING ORDER BY
) o entrambe diverse. Se io mix and match, ottengo questo:
InvalidRequest: code=2200 [Invalid query] message="Unsupported order by relation"
penso che abbia a che fare con il modo i dati vengono memorizzati su disco. Altrimenti, Cassandra avrebbe più lavoro da fare nella preparazione dei set di risultati. Se invece richiede tutto per far corrispondere o specchiare la direzione o le direzioni specificate nello CLUSTERING ORDER BY
, può semplicemente trasmettere una lettura sequenziale dal disco. Quindi è probabilmente meglio usare solo una singola colonna nella tua clausola ORDER BY
, per risultati più prevedibili.
Grazie per la tua risposta dettagliata! Apprezzo. Dalla tua risposta ho concluso 2 cose su Cassandra: (1) Non c'è modo di ottenere un set di risultati che è solo ordine da una colonna che è stata definita come Unica e (2) Quando definiamo un PK (chiave di partizione + clustering-key), quindi i risultati saranno sempre ordinati per colonne di cluster all'interno di qualsiasi chiave di partizione fissa (dobbiamo limitare a un valore di chiave di partizione), il che significa che non c'è bisogno della clausola ORDER BY, poiché non può mai cambiare l'ordine di righe (l'ordine in cui le righe sono effettivamente memorizzate), ovvero Order By è inutile. –
Ok, grazie ancora. Un'altra cosa, ho creato un indice sulla colonna "empno" della tabella "emp", non è ancora permesso ORDER BY empno. Quindi, a cosa servono gli indici? sono solo per la ricerca di record per il valore specifico della chiave dell'indice? –
Ok, questo significa semplicemente che una tabella non può essere utilizzata per ottenere set di risultati diversi con condizioni diverse e ordine di ordinamento diverso. Quindi per ogni nuovo requisito, dobbiamo creare una nuova tabella. IT significa che se abbiamo un miliardo di righe in una tabella (ad esempio la tabella delle vendite) e abbiamo bisogno della somma delle vendite (1) Prodotto-saggio, (2) Region-saggio, allora duplicheremo tutti quei miliardi di righe in 2 tabelle con una in ordine di raggruppamento di Prodotto, l'altro in ordine di raggruppamento di Regione ,. e anche se abbiamo bisogno di sommare le vendite per Salesman_id, allora costruiamo una terza tabella, di nuovo mettendo tutti quei miliardi di righe? è ragionevole? –