ApsaraDB for ClickHouse; MergeTree, Log, Integrations ve Special olmak üzere dört tablo motoru ailesini destekler. Her aile farklı iş yükleri için optimize edilmiştir. Bu konuda her motorun işlevi açıklanır ve en sık kullanılan motorlar için örnekler sunulur.
Motor ailelerine genel bakış
| Aile | En uygun olduğu alanlar | Motorlar |
|---|---|---|
| MergeTree | Arka planda işleme, bölümleme ve çoğaltma özellikleriyle yüksek aktarım hızında veri ekleme | MergeTree, ReplacingMergeTree, CollapsingMergeTree, VersionedCollapsingMergeTree, SummingMergeTree, AggregatingMergeTree, GraphiteMergeTree, Approximate Nearest Neighbor Search Indexes, Full-text Search using Inverted Indexes |
| Log | Tam tablo okuma gerektiren küçük tablolar (~1 milyon satır) için hızlı yazma | TinyLog, StripeLog, Log |
| Integrations | Harici veri kaynaklarından veri içe aktarma veya sorgulama | Kafka, MySQL, JDBC, ODBC, HDFS |
| Special | Belirli mimari gereksinimler (dağıtılmış sorgular, somutlaştırılmış görünümler, bellek içi tablolar) | Distributed, MaterializedView, Dictionary, Merge, File, NULL, Set, Join, URL, View, Memory, Buffer |
Desteklenen tüm tablo motorlarının tam referansı için bkz. Table Engines.
MergeTree ailesi
MergeTree ailesindeki motorlar, üretim ortamlarındaki iş yükleri için temel tercihtir. Yüksek hızlı veri eklemeyi, veri bölümlemeyi, birincil anahtar dizinlerini, seyrek dizinleri, veri örnekleme, veri çoğaltma ve veriler için zaman aşımı (TTL) özelliklerini desteklerler.
Tüm MergeTree motorları aynı depolama yapısını paylaşır: Veriler parçalar halinde yazılır ve arka planda birleştirilir; bu yapı log-structured merge-tree (LSM tree) benzeridir. Deduplication (tekrarlanan verilerin kaldırılması), collapsing (daraltma) ve aggregation (toplama) gibi depolama katmanı işlemleri, ekleme sırasında değil, sıkıştırma işlemi sırasında gerçekleşir.
ApsaraDB for ClickHouse'daki MergeTree, tüm ClickHouse SQL sözdizimini destekler ancak birincil anahtarlar standart SQL'den farklı çalışır. Birincil anahtar, benzersizliği zorlamak yerine sorguları hızlandırır. Sıkıştırma işleminden sonra bile yinelenen birincil anahtarlar bulunabilir.
MergeTree
MergeTree, yüksek yüklü ekleme iş yükleri için temel motordur. Veriler parçalar halinde eklenir ve ORDER BY ile tanımlanan sıralama düzenine göre arka planda birleştirilir.
Örnek: Bölümlendirilmiş MergeTree
-
create_timesütununa göre bölümlendirilmiş ve(id, create_time)üzerinde sıralanmış bir tablo oluşturun.CREATE TABLE test_tbl ON CLUSTER default ( id UInt16, create_time Date, comment Nullable(String) ) ENGINE = MergeTree() PARTITION BY create_time ORDER BY (id, create_time) PRIMARY KEY (id, create_time) SETTINGS index_granularity=8192; -
Yinelenen birincil anahtarlara sahip satırlar ekleyin.
INSERT INTO test_tbl VALUES (1, '2019-12-13', null); INSERT INTO test_tbl VALUES (1, '2019-12-13', null); INSERT INTO test_tbl VALUES (2, '2019-12-14', null); INSERT INTO test_tbl VALUES (3, '2019-12-15', null); INSERT INTO test_tbl VALUES (3, '2019-12-15', null); -
Tabloyu sorgulayın.
SELECT * FROM test_tbl;Sonuç — yinelenenler dahil tüm beş satır döndürülür:
┌─id─┬─create_time─┬─comment──┐ │ 1 │ 2019-12-13 │ NULL │ │ 1 │ 2019-12-13 │ NULL │ │ 2 │ 2019-12-14 │ NULL │ │ 3 │ 2019-12-15 │ NULL │ │ 3 │ 2019-12-15 │ NULL │ └────┴─────────────┴──────────┘ -
Sıkıştırmayı zorlayın.
OPTIMIZE TABLE test_tbl FINAL; -
Tekrar sorgulayın.
SELECT * FROM test_tbl;Sonuç — yinelenen kayıtlar hala mevcuttur. MergeTree bunları kaldırmaz.
┌─id─┬─create_time─┬─comment──┐ │ 1 │ 2019-12-13 │ NULL │ │ 1 │ 2019-12-13 │ NULL │ │ 2 │ 2019-12-14 │ NULL │ │ 3 │ 2019-12-15 │ NULL │ │ 3 │ 2019-12-15 │ NULL │ └────┴─────────────┴──────────┘
Daha fazla bilgi için bkz. MergeTree.
ReplacingMergeTree
ReplacingMergeTree, arka plan sıkıştırması sırasında aynı birincil anahtara sahip yinelenen satırları kaldırır. Sorgu zamanında benzersizlik garantisi vermez; yalnızca nihai tutarlılıkla deduplication kabul edilebilir olduğunda kullanın.
Sınırlamalar
Dağıtılmış bir kümede, aynı birincil anahtara sahip satırlar farklı parçalara yerleşebilir. Deduplication yalnızca tek bir parça içinde gerçekleşir, parçalar arasında gerçekleşmez.
Sıkıştırma tamamlanmadan önce bazı yinelenen kayıtlar hala mevcut olabilir. Sıkıştırma, öngörülemeyen bir programla arka planda çalışır.
Büyük veri kümelerinde
OPTIMIZE ... FINALkomutunu manuel olarak çalıştırmak uzun sürebilir ve bu da gerçek zamanlı deduplication işlemini pratik olmaktan çıkarır.
Daha fazla bilgi için bkz. ReplacingMergeTree.
Örnek: ReplacingMergeTree ile deduplication
-
Bir tablo oluşturun.
CREATE TABLE test_tbl_replacing ( id UInt16, create_time Date, comment Nullable(String) ) ENGINE = ReplacingMergeTree() PARTITION BY create_time ORDER BY (id, create_time) PRIMARY KEY (id, create_time) SETTINGS index_granularity=8192; -
Yinelenen birincil anahtarlara sahip satırlar ekleyin.
INSERT INTO test_tbl_replacing VALUES (1, '2019-12-13', null); INSERT INTO test_tbl_replacing VALUES (1, '2019-12-13', null); INSERT INTO test_tbl_replacing VALUES (2, '2019-12-14', null); INSERT INTO test_tbl_replacing VALUES (3, '2019-12-15', null); INSERT INTO test_tbl_replacing VALUES (3, '2019-12-15', null); -
Sıkıştırma öncesi sorgulayın — yinelenen kayıtlar hala mevcuttur.
SELECT * FROM test_tbl_replacing;┌─id─┬─create_time─┬─comment──┐ │ 1 │ 2019-12-13 │ NULL │ │ 1 │ 2019-12-13 │ NULL │ │ 2 │ 2019-12-14 │ NULL │ │ 3 │ 2019-12-15 │ NULL │ │ 3 │ 2019-12-15 │ NULL │ └────┴─────────────┴──────────┘ -
Sıkıştırmayı zorlayın.
OPTIMIZE TABLE test_tbl_replacing FINAL; -
Tekrar sorgulayın — yinelenen kayıtlar kaldırıldı.
SELECT * FROM test_tbl_replacing;┌─id─┬─create_time─┬─comment──┐ │ 1 │ 2019-12-13 │ NULL │ │ 2 │ 2019-12-14 │ NULL │ │ 3 │ 2019-12-15 │ NULL │ └────┴─────────────┴──────────┘
CollapsingMergeTree
CollapsingMergeTree, satırları yerinde güncellemek yerine bir Sign sütunu kullanarak satır durumu değişikliklerini izler; ClickHouse'un yalnızca ekleme yapılan depolama modelinde güncellemeler maliyetlidir. Her satır ya bir durum satırı (Sign = 1) ya da iptal satırı (Sign = -1) olarak işaretlenir. Sıkıştırma sırasında, aynı birincil anahtara sahip durum ve iptal satır çiftleri daraltılır ve kaldırılır.
Daraltma nasıl çalışır
Bir satırın durumunu güncellemek için:
Değiştirmek istediğiniz satırla aynı birincil anahtar değerlerine sahip
Sign = -1değerinde bir iptal satırı ekleyin.Güncellenmiş değerlerle
Sign = 1değerinde yeni bir durum satırı ekleyin.
Bir satırın durumunu silmek için: Sign dışındaki tüm sütunlarda orijinal durum satırıyla eşleşen bir iptal satırı ekleyin.
Kullanım notları
Durum ve iptal satırları sırasız eklenirse (örneğin, bir iptal satırı eklendikten sonra eşleşen durum satırı ayrı olarak gelirse) doğru şekilde daraltılmayabilir. Sırasız eklemeleri işlemek için VersionedCollapsingMergeTree kullanmayı düşünün.
Daraltma yalnızca tek bir parça içinde gerçekleşir. Dağıtılmış bir kümede, farklı düğümlerdeki aynı birincil anahtara sahip satırlar daraltılmaz.
-
Sıkıştırma tamamlanmadan önce durum ve iptal satırları birlikte bulunur. Sıkıştırma öncesi toplu iş sorguları çalıştırırken SQL kodunuzu aşağıdaki gibi ayarlayın:
COUNT()yerineSUM(Sign)kullanınSUM(col)yerineSUM(col * Sign)kullanın
Daha fazla bilgi için bkz. CollapsingMergeTree.
Örnek: CollapsingMergeTree durum güncellemeleri
-
Signsütunu içeren bir tablo oluşturun.CREATE TABLE test_tbl_collapsing ( UserID UInt64, PageViews UInt8, Duration UInt8, Sign Int8 ) ENGINE = CollapsingMergeTree(Sign) ORDER BY UserID; -
İlk durum satırını ekleyin.
INSERT INTO test_tbl_collapsing VALUES (4324182021466249494, 5, 146, 1); -
Durumu güncelleyin: Eski durum için bir iptal satırı ve yeni bir durum satırı ekleyin.
Notİptal satırını ve yeni durum satırını aynı toplu işte ekleyin. İptal satırını ve ardından durum satırını ayrı işlemlerde eklerseniz sırasız gelebilirler. Bu durumda, sıkıştırma zorlansa bile aynı birincil anahtara sahip satırlar daraltılamaz veya silinemez.
INSERT INTO test_tbl_collapsing VALUES (4324182021466249494, 5, 146, -1), -- cancel old state (4324182021466249494, 6, 185, 1); -- new state -
Sıkıştırma öncesi sorgulayın — üç satır da mevcuttur.
SELECT * FROM test_tbl_collapsing;┌────────UserID───────┬─PageViews─┬─Duration─┬─Sign──┐ │ 4324182021466249494 │ 5 │ 146 │ 1 │ │ 4324182021466249494 │ 5 │ 146 │ -1 │ │ 4324182021466249494 │ 6 │ 185 │ 1 │ └─────────────────────┴───────────┴──────────┴───────┘Sıkıştırma öncesi doğru toplu sonuçlar almak için
Signfarkında ifadeler kullanın:SELECT UserID, SUM(PageViews * Sign) AS PageViews, SUM(Duration * Sign) AS Duration FROM test_tbl_collapsing GROUP BY UserID HAVING SUM(Sign) > 0;┌────────UserID───────┬─PageViews─┬─Duration──┐ │ 4324182021466249494 │ 6 │ 185 │ └─────────────────────┴───────────┴───────────┘ -
Sıkıştırmayı zorlayın.
OPTIMIZE TABLE test_tbl_collapsing FINAL; -
Tekrar sorgulayın — yalnızca en son durum satırı kalır.
SELECT * FROM test_tbl_collapsing;┌────────UserID───────┬─PageViews─┬─Duration─┬─Sign──┐ │ 4324182021466249494 │ 6 │ 185 │ 1 │ └─────────────────────┴───────────┴──────────┴───────┘
VersionedCollapsingMergeTree
VersionedCollapsingMergeTree, CollapsingMergeTree'i, ekleme sırasından bağımsız olarak durum ve iptal satırlarının doğru eşleştirilmesini sağlayan bir Version sütunuyla genişletir. Sıkıştırma sırasında, aynı birincil anahtara, aynı Version değerine ve zıt Sign değerlerine sahip satırlar daraltılır ve kaldırılır.
Satırların sırasız gelebileceği durumlarda (örneğin, olay odaklı işlem hatlarında iptal olaylarının referans aldıkları durum olaylarından önce işlenebildiği senaryolarda) bu motoru kullanın.
CollapsingMergeTree'de olduğu gibi, toplu iş sorgularında COUNT() yerine SUM(Sign) ve SUM(col) yerine SUM(col * Sign) kullanacak şekilde ayarlama yapın.
Daha fazla bilgi için bkz. VersionedCollapsingMergeTree.
Örnek: Sırasız eklemelerle VersionedCollapsingMergeTree
-
SignveVersionsütunları içeren bir tablo oluşturun.CREATE TABLE test_tbl_Versioned ( UserID UInt64, PageViews UInt8, Duration UInt8, Sign Int8, Version UInt8 ) ENGINE = VersionedCollapsingMergeTree(Sign, Version) ORDER BY UserID; -
Önce bir iptal satırı ekleyin (sırasız).
INSERT INTO test_tbl_Versioned VALUES (4324182021466249494, 5, 146, -1, 1); -
Eşleşen durum satırını ve yeni bir durum satırını ekleyin.
INSERT INTO test_tbl_Versioned VALUES (4324182021466249494, 5, 146, 1, 1), -- state row matching the cancel above (4324182021466249494, 6, 185, 1, 2); -- new state -
Sıkıştırma öncesi sorgulayın.
SELECT * FROM test_tbl_Versioned;┌────────UserID───────┬─PageViews─┬─Duration─┬─Sign───┬Version─┐ │ 4324182021466249494 │ 5 │ 146 │ -1 │ 1 │ │ 4324182021466249494 │ 5 │ 146 │ 1 │ 1 │ │ 4324182021466249494 │ 6 │ 185 │ 1 │ 2 │ └─────────────────────┴───────────┴──────────┴────────┴────────┘Sıkıştırma öncesi doğru sonuçlar almak için
Signfarkında toplama işlemi kullanın:SELECT UserID, SUM(PageViews * Sign) AS PageViews, SUM(Duration * Sign) AS Duration FROM test_tbl_Versioned GROUP BY UserID HAVING SUM(Sign) > 0;┌────────UserID───────┬─PageViews─┬─Duration─┐ │ 4324182021466249494 │ 6 │ 185 │ └─────────────────────┴───────────┴──────────┘ -
Sıkıştırmayı zorlayın.
OPTIMIZE TABLE test_tbl_Versioned FINAL; -
Tekrar sorgulayın —
Versionsütunu, sırasız eklemeye rağmen iptal ve durum satırlarını doğru şekilde eşleştirdi.SELECT * FROM test_tbl_Versioned;┌────────UserID───────┬─PageViews─┬─Duration─┬─Sign───┬Version─┐ │ 4324182021466249494 │ 6 │ 185 │ 1 │ 2 │ └─────────────────────┴───────────┴──────────┴────────┴────────┘
SummingMergeTree
SummingMergeTree'yi MergeTree ile birlikte kullanmanızı öneririz. Ham detay verilerini bir MergeTree tablosunda saklayın ve önceden toplanmış sonuçlar için SummingMergeTree kullanın. Bu yaklaşım, birincil anahtarınız yanlış oluşturulmuşsa veri kaybını önler.
SummingMergeTree, sayısal sütunları toplayarak aynı birincil anahtara sahip satırları tek bir satırda önceden toplar. Bu işlem depolama alanını azaltır ve toplu iş sorgularını hızlandırır.
Kullanım notları
Ön toplama, ekleme sırasında değil, arka plan sıkıştırması sırasında gerçekleşir. Bazı veriler henüz toplanmamış olabilir, bu nedenle sorgularınızda her zaman
SUM()ile birlikte birGROUP BYyan tümcesi ekleyin.Yalnızca sayısal sütunlar toplanır. Birincil anahtarın parçası olmayan dize ve diğer sayısal olmayan sütunlar, toplamadan sonra rastgele bir değer alır.
Daha fazla bilgi için bkz. SummingMergeTree.
Örnek: SummingMergeTree ön toplama
-
Bir tablo oluşturun.
CREATE TABLE test_tbl_summing ( key UInt32, value UInt32 ) ENGINE = SummingMergeTree() ORDER BY key; -
Satırlar ekleyin — bazılarının anahtarı aynıdır.
INSERT INTO test_tbl_summing VALUES (1, 1), (1, 2), (2, 1); -
Sıkıştırma öncesi sorgulayın — satırlar henüz toplanmadı.
SELECT * FROM test_tbl_summing;┌─key─┬value─┐ │ 1 │ 1 │ │ 1 │ 2 │ │ 2 │ 1 │ └─────┴──────┘ -
Sıkıştırmayı zorlayın.
OPTIMIZE TABLE test_tbl_summing FINAL; -
Doğru sonuçlar almak için
GROUP BYveSUM()ile sorgulayın.SELECT key, SUM(value) FROM test_tbl_summing GROUP BY key;┌─key─┬value─┐ │ 1 │ 3 │ │ 2 │ 1 │ └─────┴──────┘
AggregatingMergeTree
AggregatingMergeTree, yalnızca SUM değil, herhangi bir toplama işlevini destekleyen daha esnek bir ön toplama motorudur. Özel AggregateFunction veri türünü ve iki aşamalı bir sorgu deseni kullanır:
Yazma aşaması: Ara toplama durumlarını depolamak için
-Statesonekli işlevleri (örneğin,sumState,uniqState) kullanın.Sorgu aşaması: Toplamayı nihailendirmek için
-Mergesonekli işlevleri (örneğin,sumMerge,uniqMerge) kullanın.
AggregatingMergeTree iki şekilde kullanılır: Yazma aşamasını otomatikleştiren bir somutlaştırılmış görünümle veya doğrudan AggregateFunction sütunlarıyla.
Daha fazla bilgi için bkz. AggregatingMergeTree.
Örnek 1: Somutlaştırılmış görünümle AggregatingMergeTree
-
Bir detay tablosu oluşturun.
CREATE TABLE visits ( UserID UInt64, CounterID UInt8, StartDate Date, Sign Int8 ) ENGINE = CollapsingMergeTree(Sign) ORDER BY UserID; -
Detay tablosunu
-Stateişlevlerini kullanarak önceden toplayan bir somutlaştırılmış görünüm oluşturun.CREATE MATERIALIZED VIEW visits_agg_view ENGINE = AggregatingMergeTree() PARTITION BY toYYYYMM(StartDate) ORDER BY (CounterID, StartDate) AS SELECT CounterID, StartDate, sumState(Sign) AS Visits, uniqState(UserID) AS Users FROM visits GROUP BY CounterID, StartDate; -
Detay tablosuna veri ekleyin. Somutlaştırılmış görünüm otomatik olarak güncellenir.
INSERT INTO visits VALUES (0, 0, '2019-11-11', 1); INSERT INTO visits VALUES (1, 1, '2019-11-12', 1); -
Somutlaştırılmış görünümü
-Mergeişlevlerini kullanarak sorgulayın.NotsumMergeveuniqMergekullanın — düzsumveuniqişlevleriAggregateFunctionsütunlarını işleyemez ve hata döndürür.SELECT StartDate, sumMerge(Visits) AS Visits, uniqMerge(Users) AS Users FROM visits_agg_view GROUP BY StartDate ORDER BY StartDate;┌──StartDate──┬─Visits─┬─Users──┐ │ 2019-11-11 │ 1 │ 1 │ │ 2019-11-12 │ 1 │ 1 │ └─────────────┴────────┴────────┘
Örnek 2: AggregateFunction sütunlarıyla AggregatingMergeTree
-
Bir detay tablosu oluşturun.
CREATE TABLE detail_table ( CounterID UInt8, StartDate Date, UserID UInt64 ) ENGINE = MergeTree() PARTITION BY toYYYYMM(StartDate) ORDER BY (CounterID, StartDate); -
Veri ekleyin.
INSERT INTO detail_table VALUES (0, '2019-11-11', 1); INSERT INTO detail_table VALUES (1, '2019-11-12', 1); -
Bir
AggregateFunctionsütunu içeren bir toplama tablosu oluşturun.CREATE TABLE agg_table ( CounterID UInt8, StartDate Date, UserID AggregateFunction(uniq, UInt64) ) ENGINE = AggregatingMergeTree() PARTITION BY toYYYYMM(StartDate) ORDER BY (CounterID, StartDate); -
uniqStatekullanarak toplanmış verileri ekleyin.Not-Stateişlevleriyle birSELECTkullanarak ekleyin. Ham değerlerle doğrudanINSERT INTO ... VALUESkullanmak tür hatasıyla başarısız olur.INSERT INTO agg_table SELECT CounterID, StartDate, uniqState(UserID) FROM detail_table GROUP BY CounterID, StartDate; -
Toplama tablosunu
uniqMergekullanarak sorgulayın.SELECT uniqMerge(UserID) AS state FROM agg_table GROUP BY CounterID, StartDate;┌─state─┐ │ 1 │ │ 1 │ └───────┘
Log ailesi
Log ailesindeki motorlar, tüm tablonun bir seferde okunduğu küçük tablolar (yaklaşık bir milyon satır) için hızlı yazma işlemleri amacıyla tasarlanmıştır.
Tüm Log motorlarının ortak özellikleri:
Veriler diske ardışık olarak eklenir
DELETEveUPDATEdesteklenmezDizinler desteklenmez
Veriler atomik olarak yazılmaz
INSERTişlemi aynı tablodakiSELECTişlemini engeller
| Motor | Eşzamanlı okuma | Depolama düzeni | Ne zaman kullanılır |
|---|---|---|---|
| TinyLog | Hayır | Sütun başına bir dosya | Performansın kritik olmadığı geçici ara veriler |
| StripeLog | Evet | Tüm sütunlar tek bir dosyada | Daha az dosya tanıtıcısıyla TinyLog'dan daha yüksek sorgu performansı |
| Log | Evet | Sütun başına bir dosya | Sütun düzeyinde erişimle TinyLog'dan daha yüksek sorgu performansı |
Integrations ailesi
Integrations ailesindeki motorlar, ApsaraDB for ClickHouse'u harici veri kaynaklarına bağlar; verileri içe aktararak veya yerinde sorgulayarak çalışır.
| Motor | Açıklama |
|---|---|
| Kafka | Kafka konularından ApsaraDB for ClickHouse'a veri okur |
| MySQL | ApsaraDB for ClickHouse'tan MySQL tablolarını doğrudan SELECT ve diğer işlemlerle sorgular |
| JDBC | Java Database Connectivity (JDBC) bağlantı dizeleri aracılığıyla veri kaynaklarına bağlanır |
| ODBC | Open Database Connectivity (ODBC) bağlantı dizeleri aracılığıyla veri kaynaklarına bağlanır |
| HDFS | Hadoop Distributed File System (HDFS) üzerinden belirtilen biçimdeki dosyaları okur |
Special ailesi
Special ailesindeki motorlar belirli mimari gereksinimleri karşılar.
| Motor | Açıklama |
|---|---|
| Distributed | Veri depolamaz. Sorguları birden çok parçaya yönlendirir ve sonuçları birleştirir. |
| MaterializedView | Önceden hesaplanmış sorgu sonuçlarını depolar. Somutlaştırılmış görünümler oluşturmak için kullanılır. |
| Dictionary | Sözlük verilerini sorgulanabilir bir tablo olarak sunar. |
| Merge | Veri depolamaz. Sanal bir birleşim olarak birden çok tablodan aynı anda okur. |
| File | Yerel bir dosyayı veri deposu olarak kullanır. |
| NULL | Yazılan tüm verileri atar. Okuma işlemleri boş sonuç döndürür. Test sırasında somutlaştırılmış görünümler için hedef olarak kullanışlıdır. |
| Set | Verileri her zaman rastgele erişimli bellekte (RAM) saklar. |
| Join | Hızlı arama için join verilerini RAM'de saklar. |
| URL | Uzak HTTP veya HTTPS uç noktalarından okur ve yazar. |
| View | Bir SELECT sorgu tanımını saklar ancak veri saklamaz. Somutlaştırılmamış bir görünüm olarak davranır. |
| Memory | Verileri RAM'de saklar. Sunucu yeniden başlatıldığında veriler kaybolur. 100 milyondan az satırı olan ve veri kalıcılığı gerektirmeyen geçici tablolar için uygundur. Genellikle ApsaraDB for ClickHouse'ta geçici tablolar için kullanılır. |
| Buffer | Yazmaları RAM'de arabelleğe alır ve yapılandırılabilir eşiklere ulaşıldığında hedef tabloya yazar. |