ApsaraDB for SelectDB üç veri modeli destekler. Tablo oluşturmadan önce doğru modeli seçin; model daha sonra değiştirilemez.
| Model | En uygun olduğu durumlar | Temel kısıtlama |
|---|---|---|
| Aggregate key modeli | Sabit desenli rapor sorguları, önceden toplanmış ölçümler | COUNT(*) maliyetlidir; her değer sütunu tek bir toplama türüne bağlıdır |
| Unique key modeli | Birincil anahtar benzersizliği gerektiren ilişkisel veriler (siparişler, kullanıcı profilleri) | ROLLUP ön toplamayı kullanamaz |
| Duplicate key modeli | Ad hoc sorgular, günlük analizi, ham veri depolama | Ön toplama yok; otomatik yinelenen öğe kaldırma yok |
Arka plan
ApsaraDB for SelectDB'de tablolar satır ve sütunlardan oluşur. Sütunlar iki kategoriye ayrılır:
Anahtar sütunlar — boyut sütunlarına karşılık gelir. Bir
CREATE TABLEifadesindeDUPLICATE KEY,AGGREGATE KEYveyaUNIQUE KEYanahtar kelimelerinden sonra tanımlanır.Değer sütunları — ölçüm sütunlarına karşılık gelir. Anahtar sütun olarak listelenmeyen tüm sütunlardır.
Bu iki kategori doğrudan üç veri modeliyle eşleşir.
Aggregate key modeli
Aggregate key modeli, yazma sırasında verileri önceden toplar. Tüm anahtar sütunlarda aynı değerlere sahip satırları içeri aktardığınızda SelectDB bunları tek bir satırda birleştirir. Her değer sütunu, CREATE TABLE ifadesinde belirttiğiniz işlev kullanılarak toplanır.
Bu modeli, günlük aktif kullanıcılar veya bölge bazlı gelir gibi sabit toplama desenlerine sahip rapor sorguları için kullanın. Sorgularınızın toplama mantığı değişiyorsa veya COUNT(*) işleminin hızlı olmasını istiyorsanız bunun yerine Duplicate key modelini veya MoW özellikli Unique key modelini kullanın. Ayrıntılar için bkz. Aggregate key modelinin sınırlamaları.
Toplama türleri
| Toplama türü | Açıklama |
|---|---|
SUM |
Satırlar arasındaki toplamı hesaplar. Sayısal değerler için geçerlidir. |
MIN |
Minimum değeri korur. Sayısal değerler için geçerlidir. |
MAX |
Maksimum değeri korur. Sayısal değerler için geçerlidir. |
REPLACE |
Önceki değeri yeni içeri aktarılan değerle değiştirir. Aynı anahtar sütunlara sahip satırlar için değerler içe aktarma sırasına göre değiştirilir. |
REPLACE_IF_NOT_NULL |
REPLACE ile aynıdır ancak null değerleri atlar. Sütun varsayılanı olarak null (boş dize değil) belirtin; aksi takdirde boş dizelerin üzerine yazılır. |
HLL_UNION |
HyperLogLog (HLL) türündeki sütunları HLL algoritması kullanarak toplar. |
BITMAP_UNION |
BITMAP sütunlarını birleşim toplamayı kullanarak toplar. |
Örnek 1: İçeri aktarma sırasında temel toplama
example_tbl1 tablosu kullanıcı ziyaret verilerini kaydeder. Anahtar sütunlar (user_id, date, city, age, sex) benzersiz kayıtları tanımlar; değer sütunları ölçümleri depolar.
| Sütun adı | Tür | Toplama türü | Açıklama |
|---|---|---|---|
| user_id | LARGEINT | Yok | Kullanıcı kimliği. |
| date | DATE | Yok | Verilerin tabloya yazıldığı tarih. |
| city | VARCHAR(20) | Yok | Kullanıcının yaşadığı şehir. |
| age | SMALLINT | Yok | Kullanıcının yaşı. |
| sex | TINYINT | Yok | Kullanıcının cinsiyeti. |
| last_visit_date | DATETIME | REPLACE | Kullanıcının en son ziyaret ettiği zaman. |
| cost | BIGINT | SUM | Kullanıcının harcadığı para miktarı. |
| max_dwell_time | INT | MAX | Kullanıcının maksimum kalış süresi. |
| min_dwell_time | INT | MIN | Kullanıcının minimum kalış süresi. |
CREATE TABLE IF NOT EXISTS test.example_tbl1
(
`user_id` LARGEINT NOT NULL COMMENT "The user ID",
`date` DATE NOT NULL COMMENT "The date on which data is written to the table",
`city` VARCHAR(20) COMMENT "The city in which the user resides",
`age` SMALLINT COMMENT "The age of the user",
`sex` TINYINT COMMENT "The gender of the user",
`last_visit_date` DATETIME REPLACE DEFAULT "1970-01-01 00:00:00" COMMENT "The last time when the user paid a visit",
`cost` BIGINT SUM DEFAULT "0" COMMENT "The amount of money that the user spends",
`max_dwell_time` INT MAX DEFAULT "0" COMMENT "The maximum dwell time of the user",
`min_dwell_time` INT MIN DEFAULT "99999" COMMENT "The minimum dwell time of the user"
)
AGGREGATE KEY(`user_id`, `date`, `city`, `age`, `sex`)
DISTRIBUTED BY HASH(`user_id`) BUCKETS 16;
Aşağıdaki satırları ekleyin:
| user_id | date | city | age | sex | last_visit_date | cost | max_dwell_time | min_dwell_time |
|---|---|---|---|---|---|---|---|---|
| 10000 | 2017-10-01 | Beijing | 20 | 0 | 2017-10-01 06:00:00 | 20 | 10 | 10 |
| 10000 | 2017-10-01 | Beijing | 20 | 0 | 2017-10-01 07:00:00 | 15 | 2 | 2 |
| 10001 | 2017-10-01 | Beijing | 30 | 1 | 2017-10-01 17:05:45 | 2 | 22 | 22 |
| 10002 | 2017-10-02 | Shanghai | 20 | 1 | 2017-10-02 12:59:12 | 200 | 5 | 5 |
| 10003 | 2017-10-02 | Guangzhou | 32 | 0 | 2017-10-02 11:20:00 | 30 | 11 | 11 |
| 10004 | 2017-10-01 | Shenzhen | 35 | 0 | 2017-10-01 10:00:15 | 100 | 3 | 3 |
| 10004 | 2017-10-03 | Shenzhen | 35 | 0 | 2017-10-03 10:20:22 | 11 | 6 | 6 |
INSERT INTO example_db.example_tbl_agg1 VALUES
(10000,"2017-10-01","Beijing",20,0,"2017-10-01 06:00:00",20,10,10),
(10000,"2017-10-01","Beijing",20,0,"2017-10-01 07:00:00",15,2,2),
(10001,"2017-10-01","Beijing",30,1,"2017-10-01 17:05:45",2,22,22),
(10002,"2017-10-02","Shanghai",20,1,"2017-10-02 12:59:12",200,5,5),
(10003,"2017-10-02","Guangzhou",32,0,"2017-10-02 11:20:00",30,11,11),
(10004,"2017-10-01","Shenzhen",35,0,"2017-10-01 10:00:15",100,3,3),
(10004,"2017-10-03","Shenzhen",35,0,"2017-10-03 10:20:22",11,6,6);
İçe aktarmadan sonra SelectDB 10000 numaralı kullanıcı için tek bir toplanmış satır depolar (1. ve 2. satırlar aynı anahtar sütunları paylaşır). Diğer tüm kullanıcıların benzersiz anahtarları vardı, bu nedenle satırları değiştirilmeden depolanır:
| user_id | date | city | age | sex | last_visit_date | cost | max_dwell_time | min_dwell_time |
|---|---|---|---|---|---|---|---|---|
| 10000 | 2017-10-01 | Beijing | 20 | 0 | 2017-10-01 07:00:00 | 35 | 10 | 2 |
| 10001 | 2017-10-01 | Beijing | 30 | 1 | 2017-10-01 17:05:45 | 2 | 22 | 22 |
| 10002 | 2017-10-02 | Shanghai | 20 | 1 | 2017-10-02 12:59:12 | 200 | 5 | 5 |
| 10003 | 2017-10-02 | Guangzhou | 32 | 0 | 2017-10-02 11:20:00 | 30 | 11 | 11 |
| 10004 | 2017-10-01 | Shenzhen | 35 | 0 | 2017-10-01 10:00:15 | 100 | 3 | 3 |
| 10004 | 2017-10-03 | Shenzhen | 35 | 0 | 2017-10-03 10:20:22 | 11 | 6 | 6 |
10000 numaralı kullanıcının satırının nasıl toplandığı:
-
last_visit_date (
REPLACE):2017-10-01 06:00:00değeri2017-10-01 07:00:00ile değiştirilir.Aynı içe aktarma partisi içinde
REPLACEtürü uygulandığında değiştirme sırası garanti edilmez. Depolanan değer her iki zaman damgasından biri olabilir. Farklı partiler arasında sonraki parti her zaman kazanır. cost (
SUM): 20 + 15 = 35.max_dwell_time (
MAX): max(10, 2) = 10.min_dwell_time (
MIN): min(10, 2) = 2.
Toplamadan sonra orijinal ham satırlar depolamada artık mevcut değildir.
Örnek 2: Yeni verilerin mevcut verilerle toplanması
Bu örnek, SelectDB'nin ikinci bir içe aktarma partisinden gelen verileri zaten depolanmış verilere karşı nasıl topladığını gösterir.
example_tbl2 tablosunu oluşturun (example_tbl1 ile aynı şema):
CREATE TABLE IF NOT EXISTS test.example_tbl2
(
`user_id` LARGEINT NOT NULL COMMENT "The user ID",
`date` DATE NOT NULL COMMENT "The date on which data is written to the table",
`city` VARCHAR(20) COMMENT "The city in which the user resides",
`age` SMALLINT COMMENT "The age of the user",
`sex` TINYINT COMMENT "The gender of the user",
`last_visit_date` DATETIME REPLACE DEFAULT "1970-01-01 00:00:00" COMMENT "The last time when the user paid a visit",
`cost` BIGINT SUM DEFAULT "0" COMMENT "The amount of money that the user spends",
`max_dwell_time` INT MAX DEFAULT "0" COMMENT "The maximum dwell time of the user",
`min_dwell_time` INT MIN DEFAULT "99999" COMMENT "The minimum dwell time of the user"
)
AGGREGATE KEY(`user_id`, `date`, `city`, `age`, `sex`)
DISTRIBUTED BY HASH(`user_id`) BUCKETS 16;
İçe aktarma partisi 1:
INSERT INTO test.example_tbl2 VALUES
(10000,"2017-10-01","Beijing",20,0,"2017-10-01 06:00:00",20,10,10),
(10000,"2017-10-01","Beijing",20,0,"2017-10-01 07:00:00",15,2,2),
(10001,"2017-10-01","Beijing",30,1,"2017-10-01 17:05:45",2,22,22),
(10002,"2017-10-02","Shanghai",20,1,"2017-10-02 12:59:12",200,5,5),
(10003,"2017-10-02","Guangzhou",32,0,"2017-10-02 11:20:00",30,11,11),
(10004,"2017-10-01","Shenzhen",35,0,"2017-10-01 10:00:15",100,3,3),
(10004,"2017-10-03","Shenzhen",35,0,"2017-10-03 10:20:22",11,6,6);
İçe aktarma partisi 2 (10004 numaralı kullanıcı için yeni veriler ekler ve 10005 numaralı kullanıcıyı tanıtır):
INSERT INTO test.example_tbl2 VALUES
(10004,"2017-10-03","Shenzhen",35,0,"2017-10-03 11:22:00",44,19,19),
(10005,"2017-10-03","Changsha",29,1,"2017-10-03 18:11:02",3,1,1);
Nihai depolanan durum:
| user_id | date | city | age | sex | last_visit_date | cost | max_dwell_time | min_dwell_time |
|---|---|---|---|---|---|---|---|---|
| 10000 | 2017-10-01 | Beijing | 20 | 0 | 2017-10-01 07:00:00 | 35 | 10 | 2 |
| 10001 | 2017-10-01 | Beijing | 30 | 1 | 2017-10-01 17:05:45 | 2 | 22 | 22 |
| 10002 | 2017-10-02 | Shanghai | 20 | 1 | 2017-10-02 12:59:12 | 200 | 5 | 5 |
| 10003 | 2017-10-02 | Guangzhou | 32 | 0 | 2017-10-02 11:20:00 | 30 | 11 | 11 |
| 10004 | 2017-10-01 | Shenzhen | 35 | 0 | 2017-10-01 10:00:15 | 100 | 3 | 3 |
| 10004 | 2017-10-03 | Shenzhen | 35 | 0 | 2017-10-03 11:22:00 | 55 | 19 | 6 |
| 10005 | 2017-10-03 | Changsha | 29 | 1 | 2017-10-03 18:11:02 | 3 | 1 | 1 |
10004 numaralı kullanıcının 2017-10-03 tarihli satırı her iki parti boyunca toplanır (cost: 11 + 44 = 55; max_dwell_time: max(6, 19) = 19; min_dwell_time: min(6, 19) = 6). 10005 numaralı kullanıcı yenidir, bu nedenle satır olduğu gibi eklenir.
ApsaraDB for SelectDB'de toplama üç aşamada gerçekleşir:
ETL (çıkarım, dönüştürme ve yükleme) aşaması — her içe aktarma partisi yazılmadan önce dahili olarak toplanır.
Veri sıkıştırma aşaması — hesaplama kümesi arka planda farklı içe aktarma partilerindeki verileri birleştirir.
Sorgu aşaması — kalan toplanmamış veriler sorgu zamanında toplanır.
Herhangi bir noktadaki toplama derecesi şeffaftır. Sorgulanan verilerin tamamen toplandığını her zaman varsayın.
Örnek 3: Aggregate key modelini kullanarak ayrıntılı verileri koruma
Anahtar sütunlara yüksek kardinaliteli bir sütun eklemek satırların aynı anahtarı paylaşmasını engeller; bu da Aggregate key modelini kullanırken tüm ham verilerin etkin bir şekilde korunmasını sağlar.
Anahtara bir timestamp sütunu (saniye hassasiyetinde) ekleyin:
CREATE TABLE IF NOT EXISTS test.example_tbl3
(
`user_id` LARGEINT NOT NULL COMMENT "The user ID",
`date` DATE NOT NULL COMMENT "The date on which data is written to the table",
`timestamp` DATETIME NOT NULL COMMENT "The time when data is written to the table, which is accurate to seconds",
`city` VARCHAR(20) COMMENT "The city in which the user resides",
`age` SMALLINT COMMENT "The age of the user",
`sex` TINYINT COMMENT "The gender of the user",
`last_visit_date` DATETIME REPLACE DEFAULT "1970-01-01 00:00:00" COMMENT "The last time when the user paid a visit",
`cost` BIGINT SUM DEFAULT "0" COMMENT "The amount of money that the user spends",
`max_dwell_time` INT MAX DEFAULT "0" COMMENT "The maximum dwell time of the user",
`min_dwell_time` INT MIN DEFAULT "99999" COMMENT "The minimum dwell time of the user"
)
AGGREGATE KEY(`user_id`, `date`, `timestamp`, `city`, `age`, `sex`)
DISTRIBUTED BY HASH(`user_id`) BUCKETS 16;
Her satır benzersiz bir timestamp değerine sahip olduğundan hiçbir iki satır aynı anahtar sütunlarını paylaşmaz; bu nedenle toplama gerçekleşmez. Tüm ham veriler korunur.
Aggregate key modelinin sınırlamaları
Aggregate key modeli her zaman tamamen toplanmış verileri sunduğundan bazı sorgular beklenmeyen sonuçlar üretebilir veya yüksek maliyete neden olabilir.
COUNT(*) ek yükü
Aşağıdaki şemaya sahip bir example_tbl8 tablosunu ele alalım:
| Sütun adı | Tür | Toplama türü | Açıklama |
|---|---|---|---|
| user_id | LARGEINT | Yok | Kullanıcı kimliği. |
| date | DATE | Yok | Verilerin tabloya yazıldığı tarih. |
| cost | BIGINT | SUM | Kullanıcının harcadığı para miktarı. |
İki parti içe aktarın:
Parti 1:
| user_id | date | cost |
|---|---|---|
| 10001 | 2017-11-20 | 50 |
| 10002 | 2017-11-21 | 39 |
Parti 2:
| user_id | date | cost |
|---|---|---|
| 10001 | 2017-11-20 | 1 |
| 10001 | 2017-11-21 | 5 |
| 10003 | 2017-11-22 | 22 |
Sıkıştırma öncesinde beş orijinal satır altta yatan depolamada hala mevcut olabilir. COUNT(*) çalıştırıldığında:
SELECT COUNT(*) FROM example_tbl8;
Beklenen sonuç: 4 (dört benzersiz anahtar kombinasyonu). Ancak SelectDB yalnızca user_id sütununu tarar ve toplamayı atlarsa 3 döndürür. Sıkıştırılmamış tüm satırları sayarsa 5 döndürür. Her ikisi de yanlıştır.
Doğru sonucu döndürmek için sorgu motorunun tüm anahtar sütunları (user_id ve date) taraması ve bunları toplaması gerekir; bu, her COUNT(*) çağrısında tam anahtar taraması anlamına gelir.
Çözüm: Sabit 1 değeri ve SUM toplama türüne sahip bir count sütunu ekleyin:
| Sütun adı | Tür | Toplama türü | Açıklama |
|---|---|---|---|
| user_id | BIGINT | Yok | Kullanıcı kimliği. |
| date | DATE | Yok | Verilerin tabloya yazıldığı tarih. |
| cost | BIGINT | SUM | Kullanıcının harcadığı para miktarı. |
| count | BIGINT | SUM | Satır sayacı. |
SELECT SUM(count) FROM table; ifadesi SELECT COUNT(*) FROM table; ifadesine eşdeğerdir ve çok daha hızlı çalışır. Bu yaklaşımın aynı anahtar sütunlara sahip satırları yeniden içe aktarmayı desteklemediğini unutmayın; bunu yapmak sayacı şişirir.
Alternatif olarak count sütununun toplama türünü sabit 1 değeriyle REPLACE olarak ayarlayın. Bu, COUNT(*) ile aynı sonucu üretir ve yinelenen anahtarların yeniden içe aktarılmasına olanak tanır.
Toplama sorgusu anlambilimi
Her değer sütunu tablo oluşturma sırasında bir toplama türüne bağlanır. Bir değer sütununda farklı bir toplama işlevi çalıştırmak anlamsal olarak yanlış sonuçlar döndürebilir. Şemayı ihtiyaç duyduğunuz toplama türlerine göre tasarlayın.
Unique key modeli
Unique key modeli değerleri toplamak yerine birincil anahtar benzersizliğini zorunlu kılmasıyla Aggregate key modelinden farklıdır. Aynı anahtar sütunlara sahip yeni satırlar geldiğinde yalnızca en son içe aktarılan satır korunur.
Bu modeli siparişler veya kullanıcı profilleri gibi benzersizlik gereksinimleri olan ilişkisel veriler için kullanın. ROLLUP ön toplamayı desteklemez.
ApsaraDB for SelectDB iki uygulama yöntemi sağlar:
Merge on Write (MoW) — içe aktarma aşamasında yinelenen öğeleri kaldırır. En iyi sorgu performansı için önerilir.
Merge on Read (MoR) — yinelenen öğe kaldırmayı sorgu zamanında uygular.
MoW (önerilen)
MoW içe aktarma sırasında üzerine yazılan satırları silindi olarak işaretler ve en son verileri doğrudan yazar. Sorgu zamanında silinen satırlar herhangi bir birleştirme işlemi olmadan filtrelenir. Bu MoR'nin toplama ek yükünü ortadan kaldırır ve çoğu senaryoda predikat itelemeyi etkinleştirerek daha hızlı toplama sorguları sağlar.
MoW ApsaraDB for SelectDB V3,0'da varsayılan olarak devre dışıdır. Tabloyu oluştururken "enable_unique_key_merge_on_write" = "true" ayarını yaparak etkinleştirin.
CREATE TABLE IF NOT EXISTS test.example_tbl6
(
`user_id` LARGEINT NOT NULL COMMENT "The user ID",
`username` VARCHAR(50) NOT NULL COMMENT "The nickname of the user",
`city` VARCHAR(20) COMMENT "The city in which the user resides",
`age` SMALLINT COMMENT "The age of the user",
`sex` TINYINT COMMENT "The gender of the user",
`phone` LARGEINT COMMENT "The phone number of the user",
`address` VARCHAR(500) COMMENT "The address of the user",
`register_time` DATETIME COMMENT "The time when the user is registered"
)
UNIQUE KEY(`user_id`, `username`)
DISTRIBUTED BY HASH(`user_id`) BUCKETS 16
PROPERTIES (
"enable_unique_key_merge_on_write" = "true"
);
MoR verileri farklı şekilde düzenledikleri için MoW'ye sorunsuz bir şekilde yükseltilemez. Geçiş yapmak için mevcut verileri yeni bir MoW tablosuna aktarmak üzere INSERT INTO unique-mow-table SELECT * FROM source_table komutunu kullanın.
Benzersiz silme işareti ve sıra sütunu MoW etkinleştirildiğinde de çalışmaya devam eder.
MoR
MoR okuma sırasında verileri birleştirerek sorgu zamanında yinelenen öğe kaldırma mantığını uygular. Tüm değer sütunlarının REPLACE olarak ayarlandığı Aggregate key modeline eşdeğerdir.
CREATE TABLE IF NOT EXISTS test.example_tbl4
(
`user_id` LARGEINT NOT NULL COMMENT "The user ID",
`username` VARCHAR(50) NOT NULL COMMENT "The nickname of the user",
`city` VARCHAR(20) COMMENT "The city in which the user resides",
`age` SMALLINT COMMENT "The age of the user",
`sex` TINYINT COMMENT "The gender of the user",
`phone` LARGEINT COMMENT "The phone number of the user",
`address` VARCHAR(500) COMMENT "The address of the user",
`register_time` DATETIME COMMENT "The time when the user is registered"
)
UNIQUE KEY(`user_id`, `username`)
DISTRIBUTED BY HASH(`user_id`) BUCKETS 16;
Yukarıdaki MoR Unique key modeli tüm değer sütunlarının REPLACE kullandığı aşağıdaki Aggregate key modeliyle dahili olarak aynıdır:
CREATE TABLE IF NOT EXISTS test.example_tbl5
(
`user_id` LARGEINT NOT NULL COMMENT "The user ID",
`username` VARCHAR(50) NOT NULL COMMENT "The nickname of the user",
`city` VARCHAR(20) REPLACE COMMENT "The city in which the user resides",
`age` SMALLINT REPLACE COMMENT "The age of the user",
`sex` TINYINT REPLACE COMMENT "The gender of the user",
`phone` LARGEINT REPLACE COMMENT "The phone number of the user",
`address` VARCHAR(500) REPLACE COMMENT "The address of the user",
`register_time` DATETIME REPLACE COMMENT "The time when the user is registered"
)
AGGREGATE KEY(`user_id`, `username`)
DISTRIBUTED BY HASH(`user_id`) BUCKETS 16;
Duplicate key modeli
Duplicate key modeli diğer ikisinden farklı olarak tüm satırları tam olarak içe aktarıldığı gibi depolar; toplama veya benzersizlik zorunluluğu yoktur. Aynı anahtar sütun değerlerine sahip birden çok satır birbirini etkilemeden birlikte bulunur.
Bu modeli tam ayrıntıya ihtiyacınız olduğu ve yinelenen öğe kaldırmaya veya ön toplamaya gerek duymadığınız günlükler gibi ham veriler üzerinde ad hoc sorgular için kullanın.
CREATE TABLE ifadesinde belirtilen anahtar sütunlar benzersiz tanımlayıcılar değil yalnızca sıralama anahtarları olarak işlev görür. İlk iki ila dört sütunu duplicate key olarak seçmenizi öneririz.
CREATE TABLE IF NOT EXISTS test.example_tbl7
(
`timestamp` DATETIME NOT NULL COMMENT "The time when the log was generated",
`type` INT NOT NULL COMMENT "The type of the log",
`error_code` INT COMMENT "The error code",
`error_msg` VARCHAR(1024) COMMENT "The error message",
`op_id` BIGINT COMMENT "The owner ID",
`op_time` DATETIME COMMENT "The time when the error was handled"
)
DUPLICATE KEY(`timestamp`, `type`, `error_code`)
DISTRIBUTED BY HASH(`type`) BUCKETS 16;
| Sütun | Tür | Sıralama anahtarı | Açıklama |
|---|---|---|---|
| timestamp | DATETIME | Evet | Günlüğün oluşturulduğu zaman. |
| type | INT | Evet | Günlük türü. |
| error_code | INT | Evet | Hata kodu. |
| error_msg | VARCHAR(1024) | Hayır | Hata mesajı. |
| op_id | BIGINT | Hayır | Sahip kimliği. |
| op_time | DATETIME | Hayır | Hatanın işlendiği zaman. |
Modeller arasında anahtar sütunlar
Anahtar sütunlar modele bağlı olarak farklı roller üstlenir:
| Model | Anahtar sütunların rolü |
|---|---|
| Duplicate key modeli | Yalnızca sıralama anahtarları — benzersiz tanımlayıcılar değil |
| Aggregate key modeli | Sıralama anahtarları ve benzersiz tanımlayıcılar |
| Unique key modeli | Sıralama anahtarları ve benzersiz tanımlayıcılar |
Veri modeli seçimi
| Senaryo | Önerilen model |
|---|---|
| Sabit desenli toplama raporları (örneğin, günlük aktif kullanıcılar, bölge bazlı gelir) | Aggregate key modeli |
| Birincil anahtar kısıtlamalı ilişkisel veriler (örneğin, siparişler, kullanıcı profilleri) | Unique key modeli (MoW) |
| Birincil anahtar verileri üzerinde yüksek performanslı toplama sorguları | MoW etkinleştirilmiş Unique key modeli |
| Ham veri analizi, günlük sorguları, ad hoc keşif | Duplicate key modeli |
| Kısmi sütun güncellemeleri | Unique key modeli — bkz. Partial Update |
Aggregate key modelini ne zaman kullanmamalısınız: COUNT(*) sorgularınızın hızlı olması gerektiğinde veya tablo oluşturma sırasında tanımlanan toplama türlerinden farklı toplama işlevleri çalıştırmanız gerektiğinde bu modelden kaçının. Aggregate key modeli yalnızca satırlar önemli ölçüde daraldığında verimlidir; çoğu satır benzersiz anahtarlara sahipse ön toplama ek yükü faydayı aşar.
MoW'nin COUNT(*) performansını nasıl iyileştirdiği
MoW sorgu zamanında toplamak yerine üzerine yazılan satırları izlemek için bir silme bit haritası kullanır. Yukarıdaki Aggregate key modeli sınırlamasından aynı iki parti senaryosunu ele alalım:
1. partiden sonra:
| user_id | date | cost | delete bit |
|---|---|---|---|
| 10001 | 2017-11-20 | 50 | false |
| 10002 | 2017-11-21 | 39 | false |
2. partiden sonra (1. partideki yinelenen satır silindi olarak işaretlenir):
| user_id | date | cost | delete bit |
|---|---|---|---|
| 10001 | 2017-11-20 | 50 | true |
| 10002 | 2017-11-21 | 39 | false |
| user_id | date | cost | delete bit |
|---|---|---|---|
| 10001 | 2017-11-20 | 1 | false |
| 10001 | 2017-11-21 | 5 | false |
| 10003 | 2017-11-22 | 22 | false |
COUNT(*), delete bit = true olan satırları atlar ve yalnızca bir sütunu tarayarak 4 sonucunu minimal ek yüklerle doğru bir şekilde döndürür. Test ortamında Unique key modelinin MoW uygulama yöntemini kullanan COUNT(*) sorguları Aggregate key modelini kullananlara kıyasla %10 kat daha yüksek performans sağlar.