摘要:同時,目錄層還可以將表的元數(shù)據(jù)轉(zhuǎn)換到該二進制前綴。默認有一個根目錄,目錄名叫,包含所有層用到的所有鍵,下層目錄叫做,用于區(qū)數(shù)據(jù)和元數(shù)據(jù)。
日常吐槽
國外文章也不是都是好文章啊,不要見到英文就覺得高大上了……
前言越來越多的關(guān)系型數(shù)據(jù)庫底層選擇基于KV構(gòu)建,例如TiDB的TiKV(RocksDB),cockroach的levelDB,MySQL的tokudb,以及被蘋果墻掉的FoundationDB。本文搶救出一篇FoundationDB的參考文章。
蘋果買下FoundationDB后,F(xiàn)oundationDB的所有公開數(shù)據(jù)均被刪除,包括Github,pypi,twitter等。
序本文包含如下內(nèi)容:
如何將關(guān)系型數(shù)據(jù)庫的數(shù)據(jù)存入KV數(shù)據(jù)庫
能否直接用KV數(shù)據(jù)庫的接口讀取數(shù)據(jù)
能否對KV數(shù)據(jù)庫直接寫數(shù)據(jù),并用SQL讀出修改后的數(shù)據(jù)
CockroachDB是如何做的
TiDB是如何做的
如何將關(guān)系型數(shù)據(jù)庫的數(shù)據(jù)存入KV數(shù)據(jù)庫簡單來說,F(xiàn)oundationDB的SQL層將數(shù)據(jù)庫的元數(shù)據(jù)(metadata)作為鍵,將對應(yīng)的數(shù)據(jù)作為值存入KV數(shù)據(jù)庫。數(shù)據(jù)庫表的有三種序列化方式,默認是foundationDB的tuple方式,當(dāng)然,也可以選擇使用protobuf序列化,或者使用column_keys的格式進行序列化,本文也只介紹foundationDB原生的序列化tuple序列化方式。
KV數(shù)據(jù)庫中的鍵是有序排列的,所有的庫、表、列甚至索引對應(yīng)的元數(shù)據(jù)由對應(yīng)的目錄層在KV數(shù)據(jù)庫中存儲成類似etcd中的“目錄結(jié)構(gòu)”的形式。目錄層對數(shù)據(jù)庫中的每個庫、表、列生成對應(yīng)的二進制字符串,該字符串在將關(guān)系型的數(shù)據(jù)映射到KV數(shù)據(jù)庫時作為區(qū)分庫、表、列的前綴。同時,目錄層還可以將表的元數(shù)據(jù)轉(zhuǎn)換到該二進制前綴。
如下實例解釋文中提到的目錄層如何工作。
CREATE TABLE schema_a.table_name_1(id INT PRIMARY KEY, c CHAR(10)); CREATE TABLE schema_a.table_name_2(id INT PRIMARY KEY);
默認有一個根目錄,目錄名叫sql,包含所有SQL層用到的所有鍵,下層目錄叫做data,用于區(qū)數(shù)據(jù)和元數(shù)據(jù)。再下層目錄叫做table,用于區(qū)分表內(nèi)容和序列數(shù)據(jù)(sequence data)。table目錄中的所有下一級的目錄均為邏輯庫(schema)的目錄,邏輯庫的下一級目錄為邏輯表(table)的目錄。
Directory | Tuple | Raw Key |
---|---|---|
sql / | (9) | x15x09 |
sql / data / | (3) | x15x03 |
sql / data / table / | (31) | x15x1F |
sql / data / table / schema_a / | (228) | x15xE4 |
sql / data / table / schema_a / table_name_1 / | (215) | x15xD7 |
sql / data / table / schema_a / table_name_2 / | (247) | x15xF7 |
當(dāng)使用tuple序列化方式時,一行的數(shù)據(jù)被存儲為一個鍵值對,鍵由上面提到的目錄的“二進制前綴”,table在Table-Group中的位置和主鍵組成,值便是由這條記錄所有的列的進行序列化后的值。
例如:對上面兩張表插入幾條數(shù)據(jù),對應(yīng)的SQL和對應(yīng)的鍵值對如下:
INSERT INTO schema_a.table_name_1 VALUES (1, "hello"), (2, "world"); INSERT INTO schema_a.table_name_2 VALUES (5);
二進制鍵 | tuple形式的鍵 | 二進制值 | tuple形式表示的值 |
---|---|---|---|
x15xD7x15x01x15x01 | (215, 1, 1) | x15x01x02hellox00 | (1, ‘hello’) |
x15xD7x15x01x15x02 | (215, 1, 2) | x15x02x02worldx00 | (2, ‘world’) |
x15xF7x15x01x15x05 | (247, 1, 5) | x15x05 | (5) |
簡單回答:能。
能否對KV數(shù)據(jù)庫直接寫數(shù)據(jù),并用SQL讀出修改后的數(shù)據(jù)安全性上來說,不能。FoundationDB數(shù)據(jù)不僅僅包含數(shù)據(jù)層,修改目錄層的數(shù)據(jù),很容易就會導(dǎo)致系統(tǒng)異常,例如缺少索引,缺少約束,缺少數(shù)據(jù)可元信息的驗證。
CockroachDB是如何做的CockroachDB中每個表都必須有主鍵,如果沒有的話,默認也要生成一個。和FoundationDB一樣,所有的表都會被映射為KV數(shù)據(jù)庫中的鍵前綴。
每一列或者列族(column family)在KV數(shù)據(jù)庫中,都會被序列化成一個值,并且作為KV數(shù)據(jù)庫中的后綴。
例如:
在mydb下面創(chuàng)建表customers,包含兩個列,一個列是name,一個列是URL,cockroach會在數(shù)據(jù)庫中存儲如下的schema信息:
Key | Values |
---|---|
/system/databases/mydb/id | 51 |
/system/tables/customer/id | 42 |
/system/desc/51/42/address | 69 |
/system/desc/51/42/url | 66 |
數(shù)據(jù)庫mydb的id是51,表customer的id是42,列address的id是69,列url的id是66。
和FoundationDB不通,cockroachDB中一個鍵值對存儲的是一條記錄中某一列的值。
Key | Values |
---|---|
/51/42/Apple/69 | 1 Infinite Loop, Cupertino, CA |
/51/42/Apple/66 | http://apple.com/ |
前綴/51/42,表示mydb庫的customer表,/Apple表示主鍵值為Apple,/66和/69表示對應(yīng)的列。
TiDB是如何做的TiDB沒有給出具體的方案,但是給出了一個大概的方案:
INSERT INTO user VALUES (1, "bob", "huang@pingcap.com"); INSERT INTO user VALUES (2, "tom", "tom@pingcap.com");
鍵存儲的是表名+索引,值存儲的是該條記錄所有列的內(nèi)容。
總結(jié)RDBMS映射到KV比較簡單,基本為:
KV中的鍵:唯一ID,通常能定位到一條記錄,或者一條記錄中的一個字段。但是,通常會映射、壓縮。
KV中的值:對應(yīng)序列化后的一條記錄,或者一條記錄中的一個字段。
另外,KV數(shù)據(jù)庫中不僅僅存儲著表的內(nèi)容,還會存儲著優(yōu)化后的索引等許多東西。
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/17580.html
閱讀 2820·2021-10-08 10:04
閱讀 3271·2021-09-10 11:20
閱讀 534·2019-08-30 10:54
閱讀 3322·2019-08-29 17:25
閱讀 2307·2019-08-29 16:24
閱讀 894·2019-08-29 12:26
閱讀 1451·2019-08-23 18:35
閱讀 1939·2019-08-23 17:53