MaxCompute, Transactional tablolar ve Delta Tablolarındaki satır düzeyindeki verileri silmek veya güncellemek için DELETE ve UPDATE işlemlerini kullanmanıza olanak tanır.
Bu konudaki komutları aşağıdaki platformlarda çalıştırabilirsiniz:
Önkoşullar
DELETE veya UPDATE işlemlerini çalıştırmadan önce, hedef Transactional tablo veya Delta Tablosu üzerinde Select ve Update izinlerine sahip olmanız gerekir. Yetkilendirme hakkında daha fazla bilgi için bkz. MaxCompute izinleri.
İşlev tanıtımı
Geleneksel veritabanlarında kullanımlarına benzer şekilde, MaxCompute'deki DELETE ve UPDATE özellikleri bir tablodaki belirli satırları silebilir veya güncelleyebilir.
DELETE veya UPDATE özelliğini kullandığınızda sistem, her silme veya güncelleme işlemi için otomatik olarak bir Delta dosyası oluşturur. Bu dosya kullanıcılar tarafından görülemez ve silinen veya güncellenen verilerle ilgili bilgileri kaydeder. Uygulama şu şekilde çalışır:
-
DELETE: Delta dosyası, Transactional tablonun temel dosyasında hangi kaydın silindiğini ve hangi silme işleminde gerçekleştiğini belirlemek içintxnid(BIGINT)verowid(BIGINT)alanlarını kullanır. Temel dosya, bir tablonun alttaki depolama biçimidir.Örneğin, t1 tablosunun temel dosyasının f1 olduğunu ve içeriğinin
a, b, c, a, bolduğunu varsayalım.DELETE FROM t1 WHERE c1='a';komutunu çalıştırdığınızda sistem ayrı birf1.deltadosyası oluşturur.txniddeğerit0isef1.deltaiçeriği((0, t0), (3, t0))olur. Bu, 0. ve 3. satırların t0 işlemi sırasında silindiğini gösterir. Başka birDELETEişlemi çalıştırırsanız sistem başka bir Delta dosyası (örneğinf2.delta) oluşturur. Bu dosya da orijinal temel dosya f1'e başvurur. Verileri sorguladığınızda sistem, silinmemiş kayıtları almak için temel dosya f1'i mevcut tüm Delta dosyalarıyla birleştirir. UPDATE: BirUPDATEişlemi, birDELETEişlemi ve birINSERT INTOişlemi olarak uygulanır.
DELETE ve UPDATE özelliklerinin aşağıdaki avantajları vardır:
-
Yazılan veri miktarının azaltılması
Daha önce MaxCompute, tablo verilerini silmek veya güncellemek için
INSERT INTOveyaINSERT OVERWRITEişlemlerini kullanıyordu. Daha fazla bilgi için bkz. INSERT INTO | INSERT OVERWRITE. Bir tablo veya bölümdeki küçük miktardaki verileri güncellemek gerektiğindeINSERTişlemi kullanmak, önce tablodan tüm verileri okumanızı,SELECTişlemi kullanarak verileri güncellemenizi ve son olarakINSERTişlemiyle tüm verileri tabloya geri yazmanızı gerektirirdi. Bu yöntem verimsizdi.DELETEveyaUPDATEözelliği kullanıldığında sistemin tüm verileri geri yazması gerekmez; bu da yazılan veri miktarını önemli ölçüde azaltır.NotKullandıkça öde faturalama yöntemi için
DELETE,UPDATEveINSERT OVERWRITEişlerinin yazma işlemleri için ücretlendirilmezsiniz. AncakDELETEveUPDATEişleri, kayıtları silme olarak işaretlemek veya güncellenmiş kayıtları geri yazmak için bölümlerden veri okumalıdır. Bu okuma işlemleri, SQL işleri için kullandıkça öde faturalama modeline göre hala ücretlendirilir. Bu nedenle, daha az veri yazılmasına rağmenDELETEveUPDATEişleriINSERT OVERWRITEişlerine kıyasla maliyetleri mutlaka düşürmez.Abonelik faturalama yöntemi için
DELETEveUPDATEdaha az yazma kaynağı tüketir.INSERT OVERWRITEile karşılaştırıldığında aynı kaynaklarla daha fazla iş çalıştırabilirsiniz.
-
Tablonun en son durumunu doğrudan okuma
Daha önce MaxCompute, toplu veri güncellemeleri için ziper tablolar kullanıyordu. Bu yöntem, bir kaydın yaşam döngüsünü izlemek için tabloya
start_dateveend_dategibi yardımcı sütunlar eklemeyi gerektiriyordu. Tablonun en son durumunu sorgulamak için sistemin mevcut durumu bulmak amacıyla zaman damgalarına göre büyük miktarda veriyi filtrelemesi gerekiyordu; bu da karmaşıktı.DELETEveUPDATEözellikleriyle tablonun en son durumunu doğrudan okuyabilirsiniz. Sistem, verilerin geçerli görünümünü sağlamak için temel dosyaları ve Delta dosyalarını birleştirir.
DELETE ve UPDATE işlemlerinin birden çok kez yürütülmesi, bir Transactional tablonun alttaki depolamasını artırır. Bu durum depolama maliyetlerini artırır ve sonraki sorgu performansını düşürür. Altta yatan verileri periyodik olarak birleştirmeniz (compact) gerekir. Birleştirme işlemleri hakkında daha fazla bilgi için bkz. Transactional tablo dosyalarını birleştirme.
Aynı hedef tablo üzerinde birden fazla iş eşzamanlı olarak çalıştırılırsa iş çakışmaları oluşabilir. Daha fazla bilgi için bkz. ACID semantiği.
Kullanım senaryoları
DELETE ve UPDATE özellikleri, bir tablo veya bölümdeki küçük miktardaki verilerin rastgele ve düşük sıklıkta silinmesi veya güncellenmesi için uygundur. Örneğin, bir tablo veya bölümdeki satırların %5'inden azı üzerinde günlük (T+1) bazda periyodik olarak toplu silme veya güncelleme işlemleri gerçekleştirebilirsiniz.
DELETE ve UPDATE özellikleri, yüksek sıklıkta güncelleme, silme veya hedef tabloya gerçek zamanlı yazma işlemleri için uygun değildir.
Sınırlamalar
-
DELETEveUPDATEözellikleri yalnızca Transactional tablolar ve Delta Tablolarında kullanılabilir ve aşağıdaki sınırlamalara tabidir:NotTransaction tabloları ve Delta Tabloları hakkında daha fazla bilgi için bkz. Transaction Table ve Delta Table Parametreleri.
Delta Tabloları için
UPDATEsözdizimi birincil anahtar (PK) sütunlarının değiştirilmesini desteklemez.
Dikkat edilecek noktalar
Bir tablo veya bölümdeki verileri silmek veya güncellemek için DELETE veya UPDATE işlemlerini kullanırken aşağıdaki hususları göz önünde bulundurun:
Bir tablodaki küçük miktardaki verileri silmek veya güncellemek ve hem işlem hem de sonraki okumalar nadiren yapılıyorsa
DELETEveUPDATEişlemlerini kullanın. Birden çok silme veya güncelleme işlemi gerçekleştirdikten sonra tablonun depolama ayak izini azaltmak için tablonun temel dosyalarını ve Delta dosyalarını birleştirin. Daha fazla bilgi için bkz. Transactional tablo dosyalarını birleştirme.-
Çok sayıda satırı (%5'ten fazlasını) nadiren siler veya günceller ancak tablo üzerindeki sonraki okuma işlemleri sık sık yapılıyorsa
INSERT OVERWRITEveyaINSERT INTOkullanın. Daha fazla bilgi için bkz. INSERT INTO | INSERT OVERWRITE.Örneğin, bir iş senaryosu günde 10 kez verilerin %10'unu silmeyi veya güncellemeyi içerebilir.
DELETEveUPDATEişlemlerinin maliyetlerinin ve sonraki okuma performansı düşüşününINSERT OVERWRITEveyaINSERT INTOkullanımına kıyasla daha düşük olup olmadığını değerlendirin. Daha uygun seçeneği belirlemek için iki yöntemin verimliliğini özel senaryonuzda karşılaştırın. Veri silme işlemi Delta dosyaları oluşturur; bu da işlemin depolamayı hemen azaltmadığı anlamına gelir.
DELETEişlemi kullanarak depolamayı azaltmak istiyorsanız tablonun temel dosyalarını ve Delta dosyalarını birleştirmeniz gerekir. Daha fazla bilgi için bkz. Transactional tablo dosyalarını birleştirme.-
MaxCompute,
DELETEveUPDATEişlerini toplu işlemler olarak çalıştırır. Her ifade kaynak tüketir ve ücrete tabidir. Verileri toplu halde silmeli veya güncellemelisiniz. Örneğin, her biri yalnızca bir veya birkaç satır üzerinde işlem yapan birçok satır düzeyinde güncelleme işi oluşturup göndermek için bir Python betiği kullanırsanız her ifade, SQL tarafından taranan giriş veri miktarına göre maliyet oluşturur. Bu tür birçok ifadenin kümülatif maliyeti giderleri önemli ölçüde artırır ve sistem verimliliğini azaltır. Aşağıda komut örnekleri verilmiştir.-
Önerilen yöntem:
UPDATE table1 SET col1= (SELECT value1 FROM table2 WHERE table1.id = table2.id AND table1.region = table2.region); -
Önerilmeyen yöntem:
UPDATE table1 SET col1=1 WHERE id='2021063001' AND region='beijing'; UPDATE table1 SET col1=2 WHERE id='2021063002' AND region='beijing';
-
Veri silme
DELETE işlemi, bir Transactional tablo veya Delta Tablosundan belirtilen koşulları karşılayan bir veya daha fazla satırı siler.
-
Sözdizimi
DELETE FROM <table_name> [[AS] alias] [WHERE <condition>]; -
Parametreler
Parametre
Gerekli
Açıklama
table_name
EvetDELETEişlemini çalıştırmak istediğiniz Transactional tablo veya Delta Tablosunun adı.
alias
Hayır
Tablo için takma ad.
where_condition
Hayır
Koşulu sağlayan verileri filtrelemek için bir WHERE yan tümcesi. WHERE yan tümcesi hakkında daha fazla bilgi için bkz. SELECT sözdizimi. WHERE yan tümcesi eklemezseniz tablodaki tüm veriler silinir. -
Örnekler
-
Örnek 1: acid_delete adlı bölümlenmemiş bir tablo oluşturun, veri aktarın ve ardından belirtilen bir koşulu sağlayan satırları silmek için
DELETEişlemini çalıştırın. Örnek komutlar aşağıdadır:-- Create a Transactional table named acid_delete. CREATE TABLE IF NOT EXISTS acid_delete (id BIGINT) TBLPROPERTIES ("transactional"="true"); -- Insert data. INSERT OVERWRITE TABLE acid_delete VALUES (1), (2), (3), (2); -- View the inserted data. SELECT * FROM acid_delete; +------------+ | id | +------------+ | 1 | | 2 | | 3 | | 2 | +------------+ -- Delete rows where id is 2. If you run this command on the MaxCompute client (odpscmd), you must enter yes or no to confirm. DELETE FROM acid_delete WHERE id = 2; -- The following command is equivalent to the one above. DELETE FROM acid_delete ad WHERE ad.id = 2; -- View the result. The table now contains only data for 1 and 3. SELECT * FROM acid_delete; +------------+ | id | +------------+ | 1 | | 3 | +------------+ -
Örnek 2: acid_delete_pt adlı bölümlenmiş bir tablo oluşturun, veri aktarın ve ardından belirtilen bir koşulu sağlayan satırları silmek için
DELETEişlemini çalıştırın. Örnek komutlar aşağıdadır:-- Create a Transactional table named acid_delete_pt. CREATE TABLE IF NOT EXISTS acid_delete_pt (id BIGINT) PARTITIONED BY (ds STRING) TBLPROPERTIES ("transactional"="true"); -- Add partitions. ALTER TABLE acid_delete_pt ADD IF NOT EXISTS PARTITION (ds = '2019'); ALTER TABLE acid_delete_pt ADD IF NOT EXISTS PARTITION (ds = '2018'); -- Insert data. INSERT OVERWRITE TABLE acid_delete_pt PARTITION (ds = '2019') VALUES (1), (2), (3); INSERT OVERWRITE TABLE acid_delete_pt PARTITION (ds = '2018') VALUES (1), (2), (3); -- View the inserted data. SELECT * FROM acid_delete_pt; +------------+------------+ | id | ds | +------------+------------+ | 1 | 2018 | | 2 | 2018 | | 3 | 2018 | | 1 | 2019 | | 2 | 2019 | | 3 | 2019 | +------------+------------+ -- Delete data where the partition is 2019 and id is 2. If you run this command on the MaxCompute client (odpscmd), you must enter yes or no to confirm. DELETE FROM acid_delete_pt WHERE ds = '2019' AND id = 2; -- View the result. The data where the partition is 2019 and id is 2 has been deleted. SELECT * FROM acid_delete_pt; +------------+------------+ | id | ds | +------------+------------+ | 1 | 2018 | | 2 | 2018 | | 3 | 2018 | | 1 | 2019 | | 3 | 2019 | +------------+------------+ -
Örnek 3: acid_delete_t adlı bir hedef tablo ve bununla ilişkili acid_delete_s adlı bir tablo oluşturun. Ardından, bir birleştirme işlemi aracılığıyla belirtilen bir koşulu sağlayan satırları silin. Örnek komutlar aşağıdadır:
-- Create a target Transactional table named acid_delete_t and an associated table named acid_delete_s. CREATE TABLE IF NOT EXISTS acid_delete_t (id INT, value1 INT, value2 INT) TBLPROPERTIES ("transactional"="true"); CREATE TABLE IF NOT EXISTS acid_delete_s (id INT, value1 INT, value2 INT); -- Insert data. INSERT OVERWRITE TABLE acid_delete_t VALUES (2, 20, 21), (3, 30, 31), (4, 40, 41); INSERT OVERWRITE TABLE acid_delete_s VALUES (1, 100, 101), (2, 200, 201), (3, 300, 301); -- Delete rows from the acid_delete_t table where the id does not match an id in the acid_delete_s table. If you run this command on the MaxCompute client (odpscmd), you must enter yes or no to confirm. DELETE FROM acid_delete_t WHERE NOT EXISTS (SELECT * FROM acid_delete_s WHERE acid_delete_t.id = acid_delete_s.id); -- The following command is equivalent to the one above. DELETE FROM acid_delete_t a WHERE NOT EXISTS (SELECT * FROM acid_delete_s b WHERE a.id = b.id); -- View the result. The table now contains only data for id 2 and 3. SELECT * FROM acid_delete_t; +------------+------------+------------+ | id | value1 | value2 | +------------+------------+------------+ | 2 | 20 | 21 | | 3 | 30 | 31 | +------------+------------+------------+ -
Örnek 4: mf_dt adlı bir Delta Tablosu oluşturun, veri aktarın ve ardından belirtilen bir koşulu sağlayan satırları silmek için DELETE işlemini çalıştırın. Örnek komutlar aşağıdadır:
-- Create a target Delta Table named mf_dt. CREATE TABLE IF NOT EXISTS mf_dt (pk BIGINT NOT NULL PRIMARY KEY, val BIGINT NOT NULL) PARTITIONED BY(dd STRING, hh STRING) tblproperties ("transactional"="true"); -- Insert data. INSERT OVERWRITE TABLE mf_dt PARTITION (dd='01', hh='02') VALUES (1, 1), (2, 2), (3, 3); -- View the inserted data. SELECT * FROM mf_dt WHERE dd='01' AND hh='02'; -- The following result is returned: +------------+------------+----+----+ | pk | val | dd | hh | +------------+------------+----+----+ | 1 | 1 | 01 | 02 | | 3 | 3 | 01 | 02 | | 2 | 2 | 01 | 02 | +------------+------------+----+----+ -- Delete data where the partition is 01 and 02, and val is 2. DELETE FROM mf_dt WHERE val = 2 AND dd='01' AND hh='02'; -- View the result. The table now contains only data where val is 1 and 3. SELECT * FROM mf_dt WHERE dd='01' AND hh='02'; -- The following result is returned: +------------+------------+----+----+ | pk | val | dd | hh | +------------+------------+----+----+ | 1 | 1 | 01 | 02 | | 3 | 3 | 01 | 02 | +------------+------------+----+----+
-
Sütun verilerini temizleme
Standart bir tablodaki sütunlardaki verileri temizlemek için CLEAR COLUMN komutunu kullanabilirsiniz. Bu işlem, artık kullanılmayan verileri diskten siler ve sütun değerlerini NULL olarak ayarlar; bu da depolama maliyetlerini azaltmaya yardımcı olur.
-
Sözdizimi
ALTER TABLE <table_name> [PARTITION ( <pt_spec>[, <pt_spec>....] )] CLEAR COLUMN column1[, column2, column3, ...] [WITHOUT TOUCH]; -
Parametreler
Parametre
Açıklama
table_name
Sütun verilerini temizlemek istediğiniz tablonun adı.column1 , column2 ...
Verilerini temizlemek istediğiniz sütunların adları.
PARTITION
Bölümü belirtir. Belirtilmezse işlem tüm bölümlere uygulanır.
pt_spec
Bölüm açıklaması; biçimi(partition_col1 = PARTITION_col_value1, PARTITION_col2 = PARTITION_col_value2, ...)şeklindedir.
WITHOUT TOUCH
BelirtilirseLastDataModifiedTimegüncellenmez. BelirtilmezseLastDataModifiedTimegüncellenir.NotŞu anda varsayılan olarak
WITHOUT TOUCHbelirtilir. Gelecek bir sürümde,WITHOUT TOUCHbelirtilmeden sütun verilerini temizleme davranışı desteklenecektir. Bu,WITHOUT TOUCHbelirtilmezseLastDataModifiedTimeöğesinin güncelleneceği anlamına gelir. -
Sınırlamalar
-
NOT NULL kısıtlamasına sahip sütunlarda sütun temizleme işlemi gerçekleştiremezsiniz. NOT NULL kısıtlamasını manuel olarak kaldırabilirsiniz:
ALTER TABLE <table_name> change COLUMN <old_col_name> NULL; ACID tabloları için sütun verilerinin temizlenmesi desteklenmez.
Kümelendirilmiş tablolar için sütun verilerinin temizlenmesi desteklenmez.
İç içe geçmiş türler içinde sütun verilerinin temizlenmesi desteklenmez.
Tüm sütunların temizlenmesi desteklenmez.
DROP TABLEkomutu daha iyi performansla aynı etkiyi sağlar.
-
-
Dikkat edilecek noktalar
CLEAR COLUMNişlemi tablonun Archive özelliğini değiştirmez.-
İç içe geçmiş bir tür sütununda yapılan
CLEAR COLUMNişlemi başarısız olabilir.Bu hata, iç içe geçmiş türler için sütunlu depolama devre dışı bırakılırken sütunlu iç içe geçmiş türler içeren bir tabloda
CLEAR COLUMNişlemi gerçekleştirirseniz oluşur. CLEAR COLUMNkomutu çevrimiçi Depolama Hizmetine bağlıdır. İş hacminin yüksek olduğu dönemlerde kuyruğa alınması gerekiyorsa görev yavaş olabilir.CLEAR COLUMNişlemi verileri okumak ve yazmak için hesaplama kaynakları gerektirir. Abonelik kullanıcıları için bu işlem hesaplama kaynaklarını tüketir. Kullandıkça öde kullanıcıları için bir SQL işiyle aynı ücretlere tabidir. (Bu özellik şu anda davetli ön izleme aşamasındadır ve geçici olarak ücretsizdir.)
-
Örnekler
-
-- Create a table. CREATE TABLE IF NOT EXISTS mf_cc(key STRING, value STRING, a1 BIGINT , a2 BIGINT , a3 BIGINT , a4 BIGINT) PARTITIONED BY(ds STRING, hr STRING); -- Add a partition. ALTER TABLE mf_cc ADD IF NOT EXISTS PARTITION (ds='20230509', hr='1641'); -- Insert data. INSERT INTO mf_cc PARTITION (ds='20230509', hr='1641') VALUES("key","value",1,22,3,4); -- Query data. SELECT * FROM mf_cc WHERE ds='20230509' AND hr='1641'; -- The following result is returned: +-----+-------+------------+------------+--------+------+---------+-----+ | key | value | a1 | a2 | a3 | a4 | ds | hr | +-----+-------+------------+------------+--------+------+---------+-----+ | key | value | 1 | 22 | 3 | 4 | 20230509| 1641| +-----+-------+------------+------------+--------+------+---------+-----+ -- Clear column data. ALTER TABLE mf_cc PARTITION(ds='20230509', hr='1641') CLEAR COLUMN key,a1 WITHOUT TOUCH; -- Query data. SELECT * FROM mf_cc WHERE ds='20230509' AND hr='1641'; -- The following result is returned. The data in the key and a1 columns has become null. +-----+-------+------------+------------+--------+------+---------+-----+ | key | value | a1 | a2 | a3 | a4 | ds | hr | +-----+-------+------------+------------+--------+------+---------+-----+ | null| value | null | 22 | 3 | 4 | 20230509| 1641| +-----+-------+------------+------------+--------+------+---------+-----+ -
Aşağıdaki grafikte,
CLEAR COLUMNkomutu kullanılarak her sütun temizlendiğindelineitemtablosunun (AliORC biçiminde) toplam depolama boyutundaki değişiklik gösterilmektedir.lineitemtablosu BIGINT, DECIMAL, CHAR, DATE ve VARCHAR dahil olmak üzere çeşitli türlerde 16 sütuna sahiptir.
Gördüğünüz gibi, tablonun 16 sütunu
CLEAR COLUMNkomutuyla sırayla NULL olarak ayarlandıktan sonra toplam depolama alanı %99,97 oranında azalmıştır (başlangıçtaki 186.783.526 bayttan 236.715 bayta).NotCLEAR COLUMNişlemiyle tasarruf edilen alan miktarı, sütunun veri türüne ve gerçek depolanan değerlerine bağlıdır. Örneğin, DECIMAL türündekil_extendedpricesütununun temizlenmesi alanın %24,2'sini (146.538.799 bayttan 111.138.117 bayta) tasarruf etmiş olup bu ortalamanın oldukça üzerindedir.Tüm sütunlar NULL olarak ayarlandığında tablo boyutu 0 değil, 236.715 bayttır. Bunun nedeni, tablonun dosya yapısının hala mevcut olmasıdır. NULL alanlar küçük miktarda depolama alanı kaplar ve sistemin dosya altbilgi bilgilerini de tutması gerekir.
-
Veri güncelleme
UPDATE işlemi, bir Transactional tablo veya Delta Tablosundaki satırlar için bir veya daha fazla sütundaki değerleri günceller.
-
Sözdizimi
-- Method 1 UPDATE <table_name> [[AS] alias] SET <col1_name> = <value1> [, <col2_name> = <value2> ...] [WHERE <where_condition>]; -- Method 2 UPDATE <table_name> [[AS] alias] SET (<col1_name> [, <col2_name> ...]) = (<value1> [, <value2> ...]) [WHERE <where_condition>]; -- Method 3 UPDATE <table_name> [[AS] alias] SET <col1_name> = <value1> [, <col2_name> = <value2>, ...] [FROM <additional_tables>] [WHERE <where_condition>]; -
Parametreler
table_name: Gerekli.
UPDATEişlemi için Transactional tablo veya Delta Tablosunun adı.alias: İsteğe bağlı. Tablo için takma ad.
col1_name, col2_name: Gerekli. Değiştirilecek sütunların adları. En az bir sütunu güncellemeniz gerekir.
value1, value2: Gerekli. Sütunlar için yeni değerler. En az bir sütun değerini güncellemeniz gerekir.
where_condition: İsteğe bağlı. Verileri filtrelemek için bir WHERE yan tümcesi. WHERE yan tümcesi hakkında daha fazla bilgi için bkz. SELECT sözdizimi. WHERE yan tümcesi eklemezseniz tablodaki tüm veriler güncellenir.
-
additional_tables: İsteğe bağlı. FROM yan tümcesi.
UPDATEdeyimi,UPDATEdeyimini basitleştirebilen FROM yan tümcesini destekler. Aşağıdaki tabloda FROM yan tümcesi kullanan bir UPDATE deyimi ile kullanmayan bir deyim karşılaştırılmaktadır.Senaryo
Örnek kod
FROM yan tümcesi olmadan
UPDATE target SET v = (SELECT MIN(v) FROM src GROUP BY k WHERE target.k = src.key) WHERE target.k IN (SELECT k FROM src);FROM yan tümcesi ile
UPDATE target SET v = b.v FROM (SELECT k, MIN(v) AS v FROM src GROUP BY k) b WHERE target.k = b.k;Kod örneklerinde gösterildiği gibi:
Hedef tablodaki bir satırı kaynak tablodan gelen birden çok satır kullanarak güncellerken sistem hangi kaynak satırın kullanılacağını bilmediğinden kaynak verilerin benzersiz olduğundan emin olmak için bir toplama işlemi kullanmanız gerekir.
FROMyan tümcesi kullanmayan sözdizimi daha az özlüdür.FROMyan tümceli sözdizimi daha basit ve anlaşılması daha kolaydır.Bir birleştirme güncellemesi gerçekleştirirken yalnızca verilerin kesişimini güncellemek istiyorsanız
FROMyan tümcesi kullanmayan sözdizimi ekstra birWHEREkoşulu gerektirir veFROMyan tümcesi kullanan sözdizimine kıyasla daha az özlüdür.
-
Örnekler
-
Örnek 1: acid_update adlı bölümlenmemiş bir tablo oluşturun, veri aktarın ve ardından belirtilen bir koşulu sağlayan satırların sütunlarını güncellemek için
UPDATEişlemini çalıştırın. Örnek komutlar aşağıdadır:-- Create a Transactional table named acid_update. CREATE TABLE IF NOT EXISTS acid_update(id BIGINT) tblproperties ("transactional"="true"); -- Insert data. INSERT OVERWRITE TABLE acid_update VALUES(1),(2),(3),(2); -- View the inserted data. SELECT * FROM acid_update; -- The following result is returned: +------------+ | id | +------------+ | 1 | | 2 | | 3 | | 2 | +------------+ -- Update the id value to 4 for all rows where id is 2. UPDATE acid_update SET id = 4 WHERE id = 2; -- View the update result. 2 has been updated to 4. SELECT * FROM acid_update; -- The following result is returned: +------------+ | id | +------------+ | 1 | | 3 | | 4 | | 4 | +------------+ -
Örnek 2: acid_update adlı bölümlenmiş bir tablo oluşturun, veri aktarın ve ardından belirtilen bir koşulu sağlayan satırların sütunlarını güncellemek için
UPDATEişlemini çalıştırın. Örnek komutlar aşağıdadır:-- Create a Transactional table named acid_update_pt. CREATE TABLE IF NOT EXISTS acid_update_pt(id BIGINT) PARTITIONED BY(ds STRING) tblproperties ("transactional"="true"); -- Add a partition. ALTER TABLE acid_update_pt ADD IF NOT EXISTS PARTITION (ds= '2019'); -- Insert data. INSERT OVERWRITE TABLE acid_update_pt PARTITION (ds='2019') VALUES(1),(2),(3); -- View the inserted data. SELECT * FROM acid_update_pt WHERE ds = '2019'; -- The following result is returned: +------------+------------+ | id | ds | +------------+------------+ | 1 | 2019 | | 2 | 2019 | | 3 | 2019 | +------------+------------+ -- Update a column in a specified row. Set the id value to 4 for all rows where the partition is 2019 and id is 2. UPDATE acid_update_pt SET id = 4 WHERE ds = '2019' AND id = 2; -- View the update result. 2 has been updated to 4. SELECT * FROM acid_update_pt WHERE ds = '2019'; -- The following result is returned: +------------+------------+ | id | ds | +------------+------------+ | 4 | 2019 | | 1 | 2019 | | 3 | 2019 | +------------+------------+ -
Örnek 3: Aynı anda birden çok sütun değerini güncellemek için acid_update_t adlı bir hedef tablo ve acid_update_s adlı ilişkili bir tablo oluşturun. Örnek komutlar aşağıdadır:
-- Create a target Transactional table to be updated, named acid_update_t, and an associated table named acid_update_s. CREATE TABLE IF NOT EXISTS acid_update_t(id INT,value1 INT,value2 INT) tblproperties ("transactional"="true"); CREATE TABLE IF NOT EXISTS acid_update_s(id INT,value1 INT,value2 INT); -- Insert data. INSERT OVERWRITE TABLE acid_update_t VALUES(2,20,21),(3,30,31),(4,40,41); INSERT OVERWRITE TABLE acid_update_s VALUES(1,100,101),(2,200,201),(3,300,301); -- Method 1: Update with constants. UPDATE acid_update_t SET (value1, value2) = (60,61); -- Query the result data in the target table for Method 1. SELECT * FROM acid_update_t; -- The following result is returned: +------------+------------+------------+ | id | value1 | value2 | +------------+------------+------------+ | 2 | 60 | 61 | | 3 | 60 | 61 | | 4 | 60 | 61 | +------------+------------+------------+ -- Method 2: Join update. The rule is a left join from acid_update_t to acid_update_s. UPDATE acid_update_t SET (value1, value2) = (SELECT value1, value2 FROM acid_update_s WHERE acid_update_t.id = acid_update_s.id); -- Query the result data in the target table for Method 2. SELECT * FROM acid_update_t; -- The following result is returned: +------------+------------+------------+ | id | value1 | value2 | +------------+------------+------------+ | 2 | 200 | 201 | | 3 | 300 | 301 | | 4 | NULL | NULL | +------------+------------+------------+ -- Method 3 (update based on the result of Method 2): Join update. The rule is to add a filter condition to update only the intersection. UPDATE acid_update_t SET (value1, value2) = (SELECT value1, value2 FROM acid_update_s WHERE acid_update_t.id = acid_update_s.id) WHERE acid_update_t.id IN (SELECT id FROM acid_update_s); -- Query the result data in the target table for Method 3. SELECT * FROM acid_update_t; -- The following result is returned: +------------+------------+------------+ | id | value1 | value2 | +------------+------------+------------+ | 2 | 200 | 201 | | 3 | 300 | 301 | | 4 | NULL | NULL | +------------+------------+------------+ -- Method 4 (update based on the result of Method 3): Join update with aggregate results. UPDATE acid_update_t SET (id, value1, value2) = (SELECT id, MAX(value1),MAX(value2) FROM acid_update_s WHERE acid_update_t.id = acid_update_s.id GROUP BY acid_update_s.id) WHERE acid_update_t.id IN (SELECT id FROM acid_update_s); -- Query the result data in the target table for Method 4. SELECT * FROM acid_update_t; -- The following result is returned: +------------+------------+------------+ | id | value1 | value2 | +------------+------------+------------+ | 2 | 200 | 201 | | 3 | 300 | 301 | | 4 | NULL | NULL | +------------+------------+------------+ -
Örnek 4: İki tabloyu içeren basit bir birleştirme sorgusu. Örnek komutlar aşağıdadır:
-- Create a target table for update, acid_update_t, and an associated table, acid_update_s. CREATE TABLE IF NOT EXISTS acid_update_t(id BIGINT,value1 BIGINT,value2 BIGINT) tblproperties ("transactional"="true"); CREATE TABLE IF NOT EXISTS acid_update_s(id BIGINT,value1 BIGINT,value2 BIGINT); -- Insert data. INSERT OVERWRITE TABLE acid_update_t VALUES(2,20,21),(3,30,31),(4,40,41); INSERT OVERWRITE TABLE acid_update_s VALUES(1,100,101),(2,200,201),(3,300,301); -- Query data from the acid_update_t table. SELECT * FROM acid_update_t; -- The following result is returned: +------------+------------+------------+ | id | value1 | value2 | +------------+------------+------------+ | 2 | 20 | 21 | | 3 | 30 | 31 | | 4 | 40 | 41 | +------------+------------+------------+ -- Query data from the acid_update_s table. SELECT * FROM acid_update_s; -- The following result is returned: +------------+------------+------------+ | id | value1 | value2 | +------------+------------+------------+ | 1 | 100 | 101 | | 2 | 200 | 201 | | 3 | 300 | 301 | +------------+------------+------------+ -- Join update. Add a filter condition to the target table to update only the intersection. UPDATE acid_update_t SET value1 = b.value1, value2 = b.value2 FROM acid_update_s b WHERE acid_update_t.id = b.id; -- The following command is equivalent to the one above. UPDATE acid_update_t a SET a.value1 = b.value1, a.value2 = b.value2 FROM acid_update_s b WHERE a.id = b.id; -- View the update result. 20 is updated to 200, 21 to 201, 30 to 300, and 31 to 301. SELECT * FROM acid_update_t; -- The following result is returned: +------------+------------+------------+ | id | value1 | value2 | +------------+------------+------------+ | 4 | 40 | 41 | | 2 | 200 | 201 | | 3 | 300 | 301 | +------------+------------+------------+ -
Örnek 5: Birden çok tabloyu içeren karmaşık bir birleştirme sorgusu. Örnek komutlar aşağıdadır:
-- Create a target table for update, acid_update_t, and an associated table, acid_update_s. CREATE TABLE IF NOT EXISTS acid_update_t(id BIGINT,value1 BIGINT,value2 BIGINT) tblproperties ("transactional"="true"); CREATE TABLE IF NOT EXISTS acid_update_s(id BIGINT,value1 BIGINT,value2 BIGINT); CREATE TABLE IF NOT EXISTS acid_update_m(id BIGINT,value1 BIGINT,value2 BIGINT); -- Insert data. INSERT OVERWRITE TABLE acid_update_t VALUES(2,20,21),(3,30,31),(4,40,41),(5,50,51); INSERT OVERWRITE TABLE acid_update_s VALUES (1,100,101),(2,200,201),(3,300,301),(4,400,401),(5,500,501); INSERT OVERWRITE TABLE acid_update_m VALUES(3,30,101),(4,400,201),(5,300,301); -- Query data from the acid_update_t table. SELECT * FROM acid_update_t; -- The following result is returned: +------------+------------+------------+ | id | value1 | value2 | +------------+------------+------------+ | 2 | 20 | 21 | | 3 | 30 | 31 | | 4 | 40 | 41 | | 5 | 50 | 51 | +------------+------------+------------+ -- Query data from the acid_update_s table. SELECT * FROM acid_update_s; -- The following result is returned: +------------+------------+------------+ | id | value1 | value2 | +------------+------------+------------+ | 1 | 100 | 101 | | 2 | 200 | 201 | | 3 | 300 | 301 | | 4 | 400 | 401 | | 5 | 500 | 501 | +------------+------------+------------+ -- Query data from the acid_update_m table. SELECT * FROM acid_update_m; -- The following result is returned: +------------+------------+------------+ | id | value1 | value2 | +------------+------------+------------+ | 3 | 30 | 101 | | 4 | 400 | 201 | | 5 | 300 | 301 | +------------+------------+------------+ -- Join update, and filter both the source and target tables in the WHERE clause. UPDATE acid_update_t SET value1 = acid_update_s.value1, value2 = acid_update_s.value2 FROM acid_update_s WHERE acid_update_t.id = acid_update_s.id AND acid_update_s.id > 2 AND acid_update_t.value1 NOT IN (SELECT value1 FROM acid_update_m WHERE id = acid_update_t.id) AND acid_update_s.value1 NOT IN (SELECT value1 FROM acid_update_m WHERE id = acid_update_s.id); -- View the update result. Only the data in the acid_update_t table with id 5 meets the condition. The corresponding value1 is updated to 500, and value2 is updated to 501. SELECT * FROM acid_update_t; -- The following result is returned: +------------+------------+------------+ | id | value1 | value2 | +------------+------------+------------+ | 5 | 500 | 501 | | 2 | 20 | 21 | | 3 | 30 | 31 | | 4 | 40 | 41 | +------------+------------+------------+ -
Örnek 6: Aşağıdaki komut, mf_dt adlı bir Delta tablosu oluşturmanın, veri aktarmanın ve belirtilen bir koşulu sağlayan satırları silmek için bir
UPDATEişlemi yürütmenin bir örneğidir:-- Create a target Delta Table named mf_dt. CREATE TABLE IF NOT EXISTS mf_dt (pk BIGINT NOT NULL PRIMARY KEY, val BIGINT NOT NULL) PARTITIONED BY(dd STRING, hh STRING) tblproperties ("transactional"="true"); -- Insert data. INSERT OVERWRITE TABLE mf_dt PARTITION (dd='01', hh='02') VALUES (1, 1), (2, 2), (3, 3); -- View the inserted data. SELECT * FROM mf_dt WHERE dd='01' AND hh='02'; -- The following result is returned: +------------+------------+----+----+ | pk | val | dd | hh | +------------+------------+----+----+ | 1 | 1 | 01 | 02 | | 3 | 3 | 01 | 02 | | 2 | 2 | 01 | 02 | +------------+------------+----+----+ -- Update a column in a specified row. Set the val value to 30 for all rows where the partition is 01 and 02, and pk is 3. -- Method 1 UPDATE mf_dt SET val = 30 WHERE pk = 3 AND dd='01' AND hh='02'; -- Method 2 UPDATE mf_dt SET val = delta.val FROM (SELECT pk, val FROM VALUES (3, 30) t (pk, val)) delta WHERE delta.pk = mf_dt.pk AND mf_dt.dd='01' AND mf_dt.hh='02'; -- View the update result. SELECT * FROM mf_dt WHERE dd='01' AND hh='02'; -- The following result is returned. The val value for the row with pk=3 is updated to 30. +------------+------------+----+----+ | pk | val | dd | hh | +------------+------------+----+----+ | 1 | 1 | 01 | 02 | | 3 | 30 | 01 | 02 | | 2 | 2 | 01 | 02 | +------------+------------+----+----+
-
Transactional tablo dosyalarını birleştirme
Bir Transactional tablonun alttaki fiziksel depolaması, doğrudan okunamayan temel dosyalardan ve Delta dosyalarından oluşur. Bir Transactional tablo üzerinde UPDATE veya DELETE işlemi çalıştırdığınızda temel dosyalar değiştirilmez. Bunun yerine Delta dosyaları eklenir. Bu, daha fazla güncelleme veya silme işlemi gerçekleştirdiğinizde tablonun daha fazla depolama alanı kapladığı anlamına gelir. Çok sayıda Delta dosyasının birikmesi depolama ve sonraki sorgu maliyetlerini artırabilir.
Aynı tablo veya bölüm üzerinde birden çok UPDATE veya DELETE işlemi çalıştırmak çok sayıda Delta dosyası oluşturur. Sistem verileri okurken hangi satırların güncellendiğini veya silindiğini belirlemek için bu Delta dosyalarını yüklemelidir. Çok sayıda Delta dosyası veri okuma performansını düşürebilir. Bu durumda depolamayı azaltmak ve veri okuma performansını artırmak için temel dosyaları ve Delta dosyalarını birleştirebilirsiniz.
-
Sözdizimi
ALTER TABLE <table_name> [PARTITION (<partition_key> = '<partition_value>' [, ...])] compact {minor|major}; -
Parametreler
Parametre
Gerekli
Açıklama
table_name
Evet
Dosyalarını birleştirmek istediğiniz Transactional tablonun adı.
partition_key
Hayır
Transactional tablo bölümlenmiş bir tabloysa bölüm anahtarı sütun adını belirtin.
partition_value
Hayır
Transactional tablo bölümlenmiş bir tabloysa bölüm anahtarı sütunu için değeri belirtin.
major|minor
Evet
Birini seçmeniz gerekir. Farklar şunlardır:
minor: Yalnızca temel dosyaları ve bunların altındaki tüm Delta dosyalarını birleştirir, Delta dosyalarını ortadan kaldırır.major: Yalnızca temel dosyaları ve bunların altındaki tüm Delta dosyalarını birleştirerek Delta dosyalarını ortadan kaldırmakla kalmaz, ayrıca tablonun karşılık gelen temel dosyaları içindeki küçük dosyaları da birleştirir. Bir temel dosya küçükse (32 MB'den az) veya Delta dosyaları varsa bu, tablo üzerinde tekrar birINSERT OVERWRITEişlemi çalıştırmaya eşdeğerdir. Ancak temel dosya yeterince büyükse (32 MB'a eşit veya bundan büyük) ve Delta dosyası yoksa yeniden yazılmaz. -
Dikkat edilecek noktalar
compactişlemi tarafından birleştirilen küçük dosyalar bir gün sonra silinir. Bu küçük dosyalara bağımlı bir geçmişi geri yüklemek için yerel yedekleme özelliğini kullanırsanız dosyalar eksik olduğu için kurtarma işlemi başarısız olur. -
Örnekler
-
Örnek 1: acid_delete Transactional tablosu için dosyaları birleştirin. Örnek komut aşağıdadır:
ALTER TABLE acid_delete compact minor;Aşağıdaki sonuç döndürülür:
Summary: Nothing found to merge, set odps.merge.cross.paths=true if cross path merge is permitted. OK -
Örnek 2: acid_update_pt Transactional tablosu için dosyaları birleştirin. Örnek komut aşağıdadır:
ALTER TABLE acid_update_pt PARTITION (ds = '2019') compact major;Aşağıdaki sonuç döndürülür:
Summary: table name: acid_update_pt /ds=2019 instance count: 2 run time: 6 before merge, file count: 8 file size: 2613 file physical size: 7839 after merge, file count: 2 file size: 679 file physical size: 2037 OK
-
SSS
-
Sorun 1:
Sorun açıklaması: Bir
UPDATEdeyimi çalıştırdığımdaODPS-0010000:System internal error - fuxi job failed, caused by: Data Set should contain exactly one rowhatası bildiriliyor.-
Neden: Güncellenecek satırlar ile alt sorgu sonucundaki veriler arasında birebir karşılık yoktur. Sistem hangi satırın güncelleneceğini belirleyemez. Örnek bir komut aşağıdadır:
UPDATE store SET (s_county, s_manager) = (SELECT d_country, d_manager FROM store_delta sd WHERE sd.s_store_sk = store.s_store_sk) WHERE s_store_sk IN (SELECT s_store_sk FROM store_delta);SELECT d_country, d_manager FROM store_delta sd WHERE sd.s_store_sk = store.s_store_skalt sorgusu store_delta ile birleştirmek için kullanılır ve store'u güncellemek üzere store_delta'dan alınan veriler kullanılır. Store tablosundaki s_store_sk sütununda[1, 2, 3]olmak üzere üç satır veri bulunduğunu varsayalım. Store_delta tablosundaki s_store_sk sütununda[1, 1]olmak üzere iki satır veri varsa birebir karşılık yoktur ve yürütme başarısız olur. Çözüm: Güncellenecek satırların alt sorgu sonucundaki verilerle birebir karşılık geldiğinden emin olun.
-
Sorun 2:
Sorun açıklaması: DataWorks DataStudio'da
compactkomutunu çalıştırdığımdaODPS-0130161:[1,39] Parse exception - invalid token 'minor', expect one of 'StringLiteral','DoubleQuoteStringLiteral'hatası bildiriliyor.Neden: DataWorks için özel kaynak grubundaki MaxCompute istemci sürümü
compactkomutunu desteklemiyor.Çözüm: DataWorks DingTalk grubu aracılığıyla teknik destek ekibiyle iletişime geçerek özel kaynak grubundaki MaxCompute istemci sürümünü yükseltin.