1. 程式人生 > >Cassandra雜記10-大話Cassandra資料模型

Cassandra雜記10-大話Cassandra資料模型

Cassandra是一個開源的分散式資料庫,結合了Dynamo的Key/Value與Bigtable的面向列的特點。

Cassandra的特點如下:

1.靈活的schema:不需要象資料庫一樣預先設計schema,增加或者刪除欄位非常方便(on the fly)。

2.支援range查詢:可以對Key進行範圍查詢。

3.高可用,可擴充套件:單點故障不影響叢集服務,可線性擴充套件。

我們可以將Cassandra的資料模型想象成一個四維或者五維的Hash。

Column

Column是Cassandra中最小的資料單元。它是一個3元的資料型別,包含:name,value和timestamp。

將一個Column用JSON的形式表現出來如下:

   1: {  // 這是一個column
   2:     name: "逖靖寒的世界",
   3:     value: "[email protected]",
   4:     timestamp: 123456789
   5: } 

為了簡單起見,我們可以忽略timestamp。就把column想象成一個name/value即可。

注意,這裡提到的name和value都是byte[]型別的,長度不限。

SuperColumn

我們可以將SuperColumn想象成Column的陣列,它包含一個name,以及一系列相應的Column。

將一個SuperColumn用JSON的形式表現如下:

   1: {   // 這是一個SuperColumn
   2:     name: "逖靖寒的世界",
   3:     // 包含一系列的Columns
   4:     value: {
   5:         street: {name: "street", value: "1234 x street", timestamp: 123456789},
   6:         city: {name: "city", value: "san francisco", timestamp: 123456789},
   7:         zip: {name: "zip", value: "94107"
, timestamp: 123456789},
   8:     }
   9: }

Columns和SuperColumns都是name與value的組合。最大的不同在於Column的value是一個“string”,而SuperColumn的value是Columns的Map。

還有一點需要注意的是:SuperColumn’本身是不包含timestamp的。

ColumnFamily

ColumnFamily是一個包含了許多Row的結構,你可以將它想象成RDBMS中的Table。

每一個Row都包含有client提供的Key以及和該Key關聯的一系列Column。

我們可以看看結構:

   1: UserProfile = { // 這是一個ColumnFamily
   2:     phatduckk: {   // 這是對應ColumnFamily的key
   3:         // 這是Key下對應的Column
   4:         username: "gpcuster",
   5:         email: "[email protected]",
   6:         phone: "6666"
   7:     }, // 第一個row結束
   8:     ieure: {   // 這是ColumnFamily的另一個key
   9:         //這是另一個Key對應的column
  10:         username: "pengguo",
  11:         email: "[email protected]",
  12:         phone: "888"
  13:         age: "66"
  14:     },
  15: }

ColumnFamily的型別可以為Standard,也可以是Super型別。

我們剛剛看到的那個例子是一個Standard型別的ColumnFamily。Standard型別的ColumnFamily包含了一系列的Columns(不是SuperColumn)。

Super型別的ColumnFamily包含了一系列的SuperColumn,但是並不能像SuperColumn那樣包含一系列Standard ColumnFamily。

這是一個簡單的例子:

   1: AddressBook = { // 這是一個Super型別的ColumnFamily
   2:     phatduckk: {    // key
   3:         friend1: {street: "8th street", zip: "90210", city: "Beverley Hills", state: "CA"}, 
   4:         John: {street: "Howard street", zip: "94404", city: "FC", state: "CA"},
   5:         Kim: {street: "X street", zip: "87876", city: "Balls", state: "VA"},
   6:         Tod: {street: "Jerry street", zip: "54556", city: "Cartoon", state: "CO"},
   7:         Bob: {street: "Q Blvd", zip: "24252", city: "Nowhere", state: "MN"},
   8:         ...
   9:     }, // row結束
  10:     ieure: {     // key
  11:         joey: {street: "A ave", zip: "55485", city: "Hell", state: "NV"},
  12:         William: {street: "Armpit Dr", zip: "93301", city: "Bakersfield", state: "CA"},
  13:     },
  14: }

Keyspace

Keyspace是我們的資料最外層,你所有的ColumnFamily都屬於某一個Keyspace。一般來說,我們的一個程式應用只會有一個Keyspace。

簡單測試

我們將Cassandra執行起來以後,啟動命令列,執行如下操作:

cassandra> set Keyspace1.Standard1['jsmith']['first'] = 'John'
Value inserted.
cassandra> set Keyspace1.Standard1['jsmith']['last'] = 'Smith'
Value inserted.
cassandra> set Keyspace1.Standard1['jsmith']['age'] = '42'
Value inserted.

這個時候,Cassandra中就已經有3條資料了。

其中插入資料的各個欄位含義如下:

image

接下來,我們執行查詢操作:

cassandra> get Keyspace1.Standard1['jsmith']
  (column=age, value=42; timestamp=1249930062801)
  (column=first, value=John; timestamp=1249930053103)
  (column=last, value=Smith; timestamp=1249930058345)
Returned 3 rows.

這樣,我們就可以將之前插入的資料查詢出來了。

排序

有一點需要明確,我們使用Cassandra的時候,資料在寫入的時候就已經排好順序了。

在某一個Key內的所有Column都是按照它的Name來排序的。我們可以在storage-conf.xml檔案中指定排序的型別。

目前Cassandra提供的排序型別有:BytesType, UTF8Type,LexicalUUIDType, TimeUUIDType, AsciiType,和LongType。

現在假設你的原始資料如下:

{name: 123, value: "hello there"},
{name: 832416, value: "kjjkbcjkcbbd"},
{name: 3, value: "101010101010"},
{name: 976, value: "kjjkbcjkcbbd"}

當我們storage-conf.xml檔案中指定排序的型別為LongType時:

<!--
      ColumnFamily 在 storage-conf.xml 中定義
-->
<ColumnFamily CompareWith="LongType" Name="CF_NAME_HERE"/>

排序後的資料就是這樣的:

{name: 3, value: "101010101010"},  
{name: 123, value: "hello there"},
{name: 976, value: "kjjkbcjkcbbd"},
{name: 832416, value: "kjjkbcjkcbbd"}

如果我們指定排序的型別為UTF8Type

<!--
      ColumnFamily 在 storage-conf.xml 中定義

-->
<ColumnFamily CompareWith="UTF8Type" Name="CF_NAME_HERE"/>

排序後的資料就是這樣的:

{name: 123, value: "hello there"},   
{name: 3, value: "101010101010"},
{name: 832416, value: "kjjkbcjkcbbd"},
{name: 976, value: "kjjkbcjkcbbd"}

大家可以看到,指定的排序型別不一樣,排序的結果也是完全不同的。

對於SuperColumn,我們有一個額外的排序維度,所以我們可以指定CompareSubcolumnsWith來進行另一個維度的排序型別。

假設我們的原始資料如下:

{ // first SuperColumn from a Row
    name: "workAddress",
    // and the columns within it
    value: {
        street: {name: "street", value: "1234 x street"},
        city: {name: "city", value: "san francisco"},
        zip: {name: "zip", value: "94107"}
    }
},
{ // another SuperColumn from same Row
    name: "homeAddress",
    // and the columns within it
    value: {
        street: {name: "street", value: "1234 x street"},
        city: {name: "city", value: "san francisco"},
        zip: {name: "zip", value: "94107"}
    }
}

然後我們定義CompareSubcolumnsWith和CompareWith的排序型別都是UTF8Type,那麼排序後的結果為:

{
    // this one's first b/c when treated as UTF8 strings
    { // another SuperColumn from same Row
        // This Row comes first b/c "homeAddress" is before "workAddress"           
        name: "homeAddress",
        // the columns within this SC are also sorted by their names too
        value: {
            // see, these are sorted by Column name too
            city: {name: "city", value: "san francisco"},               
            street: {name: "street", value: "1234 x street"},
            zip: {name: "zip", value: "94107"}
        }
    },       
    name: "workAddress",
    value: {
        // the columns within this SC are also sorted by their names too
        city: {name: "city", value: "san francisco"},           
        street: {name: "street", value: "1234 x street"},
        zip: {name: "zip", value: "94107"}
    }
}

再額外提一句,Cassandra的排序功能是允許我們自己實現的,只要你繼承org.apache.cassandra.db.marshal.IType就可以了。

相關推薦

Cassandra雜記10-大話Cassandra資料模型

Cassandra是一個開源的分散式資料庫,結合了Dynamo的Key/Value與Bigtable的面向列的特點。 Cassandra的特點如下: 1.靈活的schema:不需要象資料庫一樣預先設計schema,增加或者刪除欄位非常方便(on the fly)。 2.支

Cassandra NoSQL資料模型設計指南

摘要:本文通過一個簡單的例項詳細介紹了Cassandra資料建模的五個步驟。以下是譯文。 我們最近在Instaclustr發表了一篇有關在Cassandra中經常出現的資料建模錯誤的文章。這篇文章非常受歡迎,並促使我思考如何設計出高質量的Cassandra

Cassandra資料模型設計最佳實踐(上)

本文是Cassandra資料模型設計第一篇(全兩篇),該系列文章包含了eBay使用Cassandra資料模型設計的一些實踐。其中一些最佳實踐我們是通過社群學到的,有些對我們來說也是新知識,還有一些仍然具有爭議性,可能在要通過進一步的實踐才能從中獲益。 本文中,我將會講解一些

Cassandra 資料模型設計總結

結合前段時間使用Cassandra使用過程,團隊簡單總結了Cassandra  資料模型設計,請大家斧正。 1、相關概念 Column:Cassandra中的最基本的儲存單元,用於儲存某一行的資訊;

Cassandra資料模型設計最佳實踐(上部)

本文是Cassandra資料模型設計第一篇(全兩篇),該系列文章包含了eBay使用Cassandra資料模型設計的一些實踐。其中一些最佳實踐我們是通過社群學到的,有些對我們來說也是新知識,還有一些仍然具有爭議性,可能在要通過進一步的實踐才能從中獲益。 本文中,我將會講解

列資料庫--Cassandra資料模型

1. 概述 Cassandra是一套開源分散式NoSQL資料庫系統,設計思想採用了google的BigTable的資料模型和Amazon的Dynamo的完全分散式架構,因而它具有很好的擴充套件性且不存在單點故障。 本文假設讀者已經具有了SQL資料庫的基本知識,為了幫助讀者

Cassandra原始碼學習:資料模型

Column Column是Cassandra中最小的資料單元,它是一個三元的資料型別,包含name,value,timestamp. Column必須有一個名稱,類似於JAVA中的字串,應用建立後可以動態地設定,Column可以在name上建索引。不要求每個name都有對應的value,value

Cassandra學習筆記之資料模型

Column Column是Cassandra中最小的資料單元,它是一個三元的資料型別,包含name,value,timestamp. Column必須有一個名稱,類似於JAVA中的字串,應用建立後可以動態地設定,Column可以在name上建索引。不要求每個name都有

cassandra資料模型

        ColumnFamily裡的每條記錄都是一個key-value對,value部分存放的是無限制的Columns。每個Column都有一個Column Name和value,因此Column實際也是一個key-value對。但Column的value部分已經是最基本的資料儲存單元,不能再向下嵌套

[Cassandra] Cassandra3.10建立表時“Column family ID mismatch”報錯解決

  記一次cassandra建立表時“Column family ID mismatch”報錯解決 環境:CentOS6.7 + JDK8 + Cassandra3.10   問題: Cassandra建立表時報錯: [email prote

Cassandra雜記9-增刪改查以及高階特性

     PreparedStatement prepareStatement = session.prepare(REMOVE_STUDENT); BoundStatement bindStatement = new BoundStatement(prepareStatement)

Cognos 10 體驗魅力之6: 第一個元資料模型

為什麼需要元資料模型 您已經熟悉使用 Cognos 來建立報表,進行自助式設計分析,然而這些需要的建立的應用都依賴於對應的元資料模型,使用者使用元資料模型對他們的資料來源進行分析和報告。元資料模型是整個 Cognos 應用的基礎,它是一個或多個數據源中資訊的業務演示。基於這

hive:資料模型—桶表

概述 桶的概念,主要是為效能考慮,可以理解為對分割槽內列,進行再次劃分,提高效能。在底層,一個桶其實是一個檔案。如果桶劃分過多,會導致檔案數量暴增,一旦達到系統檔案數量的上限,就杯具了。哪種是最優數量,這個哥也不知道。 桶表是對資料進行雜湊取值,然後放到不同檔案中儲存。 資料載入到桶表時

資料倉庫】1.資料模型

0x00 前言 翻出來之前零零散散寫的資料倉庫的內容,重新修正整理成一個系列,此為第一篇《資料模型》。 資料倉庫包含的內容很多,比如系統架構、建模和方法論。對應到具體工作中的話,它可以包含下面的這些內容: 以Hadoop、Spark、Hive等元件為中心的資料架構體系

django建立資料模型

Y13 1、在app功能模組資料夾下的models.py中建立資料庫表格對應的資料模型,如: from django.db import models """ # 用來建立Mysql資料庫表格對應的資料模型。該模型相當於資料的載體用來完成開 發人員對錶格資料的增刪改查操作 #

python3 遞迴實現二分查詢, 區分邊界資訊, 複雜度O(log(n)), 大概能算到10^7規模資料

def binarySearch(arr, l, r, target): #[l,n] 前閉後閉範圍內查詢target #如果不在裡面 if (target < arr[l] or target > arr[r]): return -1

[ZooKeeper] 資料模型

資料模型 原文連結:http://blog.51cto.com/nileader/946788 作者:@ni掌櫃 [email protected] 正文 本文主要講述ZooKeeper的資料模型,包括ZooKeeper的資料檢視,節點的層次結構以及節點型別等基本屬性

SpringMVC_處理資料模型(@ModelAndView、@Map、@SessionAttributes)

1. 處理模型資料之ModelAndView 首先ModelAndView 分為兩部分:model和view。model負責的是從後面接收回來的引數,view就是檢視就是指定的jsp頁面。例如:ModelAndView mv = new ModelAndView(“test”

FMDB(資料庫)與Model(資料模型)的結合使用(CRUD)

一. 宣告   本文意在探討, 也參考了幾位大神的文章, 在文章最後我會把連結貼出來, 如果有敘述錯誤的地方, 請大神們指正! 二. 前言   最近在做專案的時候, 我們有一個"我的訊息"模組, 是這樣設計的, 在本地建立一個數據庫, 收到遠端推送的訊息, 將該條訊息存入資料庫, 進

T-SQL執行內幕(10)——讀取資料

本文屬於SQL Server T-SQL執行內幕系列     關係型資料庫的資料訪問操作總是從記憶體的快取中讀取資料而不是從磁碟中讀取。這個快取稱為Buffer Pool。如果資料訪問操作符未能在快取中找到所需的資料,那麼就需要從磁碟中載入