Dizin Tablosu düzeniIndex Table pattern

Sorguların sıklıkla başvurduğu veri kaynaklarındaki alanlar üzerinden dizin oluşturun.Create indexes over the fields in data stores that are frequently referenced by queries. Bu düzen, uygulamaların bir veri deposundan alınacak verileri daha hızlı bir şekilde bulmasına olanak vererek sorgu performansını iyileştirebilir.This pattern can improve query performance by allowing applications to more quickly locate the data to retrieve from a data store.

Bağlam ve sorunContext and problem

Birçok veri deposu birincil anahtarı kullanan varlık koleksiyonları için verileri düzenler.Many data stores organize the data for a collection of entities using the primary key. Uygulamalar bu anahtarı verileri bulmak ve almak için kullanabilir.An application can use this key to locate and retrieve data. Şekilde, müşteri bilgileri içeren bir veri deposu örneği gösterilmektedir.The figure shows an example of a data store holding customer information. Birincil anahtar müşteri kimliğidir.The primary key is the Customer ID. Şekilde birincil anahtara (Müşteri Kimliği) göre düzenlenen kullanıcı bilgileri gösterilmektedir.The figure shows customer information organized by the primary key (Customer ID).

Şekil 1 - Birincil anahtara (Müşteri Kimliği) göre düzenlenen kullanıcı bilgileri

Birincil anahtar, bu anahtarın değerine göre veri alan sorgular için değerli olsa da, bir uygulamanın bazı diğer temel alanlara göre veri alması gerekirse birincil anahtarı kullanması mümkün olmayabilir.While the primary key is valuable for queries that fetch data based on the value of this key, an application might not be able to use the primary key if it needs to retrieve data based on some other field. Müşteriler örneğinde uygulama, verileri yalnızca diğer bir özniteliğin değerine başvurarak sorguluyorsa, örneğin müşterinin bulunduğu şehir gibi, Müşteri Kimliği birincil anahtarını kullanamaz.In the customers example, an application can't use the Customer ID primary key to retrieve customers if it queries data solely by referencing the value of some other attribute, such as the town in which the customer is located. Böyle bir sorguyu gerçekleştirmek için uygulamanın her müşteri kaydını alıp incelemesi gerekebilir ve bu yavaş bir işlem olabilir.To perform a query such as this, the application might have to fetch and examine every customer record, which could be a slow process.

Pek çok ilişkisel veritabanı yönetim sistemi ikincil dizinler destekler.Many relational database management systems support secondary indexes. İkincil dizin, bir veya daha fazla birincil olmayan (ikincil) anahtar alanlarına göre düzenlenmiş ayrı bir veri yapısıdır ve dizini oluşturulmuş her bir değerin verilerinin nerede depolandığını belirtir.A secondary index is a separate data structure that's organized by one or more nonprimary (secondary) key fields, and it indicates where the data for each indexed value is stored. İkincil dizindeki öğeler, hızlı veri arama olanağı sunmak için genellikle ikincil anahtarların değerlerine göre sıralanır.The items in a secondary index are typically sorted by the value of the secondary keys to enable fast lookup of data. Bu dizinler çoğunlukla veritabanı yönetim sistemi tarafından otomatik olarak sürdürülür.These indexes are usually maintained automatically by the database management system.

Uygulamanızın gerçekleştirdiği farklı sorguları desteklemek için gereksinim duyduğunuz kadar çok ikincil dizin oluşturabilirsiniz.You can create as many secondary indexes as you need to support the different queries that your application performs. Örneğin, Müşteri Kimliğinin birincil anahtar olduğu ilişkisel bir veritabanındaki Müşteriler tablosunda, uygulama müşterileri bulundukları şehre göre arıyorsa şehir alanına ikincil bir dizin eklemek faydalı olur.For example, in a Customers table in a relational database where the Customer ID is the primary key, it's beneficial to add a secondary index over the town field if the application frequently looks up customers by the town where they reside.

İkincil dizinler ilişkisel sistemlerde sık kullanılsa da, bulut uygulamaları tarafından kullanılan çoğu NoSQL veri deposu eşdeğer bir özellik sunmaz.However, although secondary indexes are common in relational systems, most NoSQL data stores used by cloud applications don't provide an equivalent feature.

ÇözümSolution

Veri deposu ikincil dizinleri desteklemiyorsa, bunları el ile kendi dizin tablolarınızı oluşturarak kullanabilirsiniz.If the data store doesn't support secondary indexes, you can emulate them manually by creating your own index tables. Dizin tabloları, verileri belirli anahtar verilere göre düzenler.An index table organizes the data by a specified key. Bir dizin tablosunu yapılandırmak için genellikle gereken ikincil dizin sayısına ve uygulamanın gerçekleştirdiği sorguların yapısına göre üç strateji kullanılır.Three strategies are commonly used for structuring an index table, depending on the number of secondary indexes that are required and the nature of the queries that an application performs.

İlk strateji, her dizin tablosundaki verileri yinelemek ancak farklı anahtarlara (tam normalleştirilmişlikten çıkarma) göre düzenlemektir.The first strategy is to duplicate the data in each index table but organize it by different keys (complete denormalization). Sonraki şekilde, aynı müşteri bilgilerini Şehir ve Soyadı bilgilerine göre düzenleyen dizin tabloları gösterilir.The next figure shows index tables that organize the same customer information by Town and LastName.

Şekil 2 - Veri her dizin tablosunda yineleniyor

Veriler, her anahtar kullanılarak kaç defa sorgulandığı açısından görece statik ise bu strateji uygundur.This strategy is appropriate if the data is relatively static compared to the number of times it's queried using each key. Veriler daha dinamik ise, her dizin tablosunu işleme yükü bu yaklaşımın kullanışlı olmayacağı kadar büyük hale gelir.If the data is more dynamic, the processing overhead of maintaining each index table becomes too large for this approach to be useful. Ayrıca, veri hacmi çok büyükse, yinelenen verileri depolamak için gereken alanı önemli ölçüde büyük olabilir.Also, if the volume of data is very large, the amount of space required to store the duplicate data is significant.

İkinci strateji, farklı anahtarlara göre düzenlenen ve özgün verilere birincil anahtarı yinelemek yerine bu anahtarı kullanarak ulaşan (aşağıdaki şekilde gösterilmiştir) normalleştirilmiş dizin tabloları oluşturmaktır.The second strategy is to create normalized index tables organized by different keys and reference the original data by using the primary key rather than duplicating it, as shown in the following figure. Özgün verilere olgu tablosu adı verilir.The original data is called a fact table.

Şekil 3 - Verilere her dizin tablosu tarafından başvuruda bulunulur

Bu teknik, alan tasarrufu yapılmasını sağlar ve yinelenen verileri saklama yükünü azaltır.This technique saves space and reduces the overhead of maintaining duplicate data. Olumsuz yönüyse, uygulamanın ikincil bir anahtar kullanarak verileri bulmak üzere iki arama işlemi gerçekleştirmesi gerekmesidir.The disadvantage is that an application has to perform two lookup operations to find data using a secondary key. Dizin tablosundaki veriler için birincil anahtarı bulmalıdır, ardından birincil anahtarla olgu tablosundaki verilere bakmalıdır.It has to find the primary key for the data in the index table, and then use the primary key to look up the data in the fact table.

Üçüncü strateji, sık alınan alanları yineleyen farklı anahtarlara göre düzenlenmiş kısmen normalleştirilmiş dizin tabloları oluşturmaktır.The third strategy is to create partially normalized index tables organized by different keys that duplicate frequently retrieved fields. Daha az sıklıkta erişilen erişim alanlarına erişmek için olgu tablosuna başvurun.Reference the fact table to access less frequently accessed fields. Aşağıdaki şekilde, her dizin tablosunda sıklıkla erişilen verilerin nasıl yinelendiği gösterilmiştir.The next figure shows how commonly accessed data is duplicated in each index table.

Şekil 4 - Her dizin tablosunda sıklıkla erişilen verilerin nasıl yinelendiği

Bu strateji ile ilk iki yaklaşım arasında bir denge kurabilirsiniz.With this strategy, you can strike a balance between the first two approaches. Genel sorgular için veriler tek bir arama kullanılarak alınabilir, alanı ve bakım yükü de tüm veri kümesinin çoğaltılmasında olduğu kadar fazla değildir.The data for common queries can be retrieved quickly by using a single lookup, while the space and maintenance overhead isn't as significant as duplicating the entire data set.

Bir uygulama sık sık veri değerlerinin (örneğin "Redmond’da yaşayan ve soyadı Yılmaz olan tüm müşterileri bul") bir bileşimini belirterek sorgulama yapıyorsa, öğelerin anahtarlarını dizin tablosunda Şehir ve Soyadı özniteliklerinin bir birleşimi olarak uygulayabilirsiniz.If an application frequently queries data by specifying a combination of values (for example, “Find all customers that live in Redmond and that have a last name of Smith”), you could implement the keys to the items in the index table as a concatenation of the Town attribute and the LastName attribute. Sonraki şekilde bileşik anahtara göre bir dizin tablosu gösterilir.The next figure shows an index table based on composite keys. Anahtarlar önce Şehre göre, sonra da Şehir için aynı değere sahip olan kayıtlar için Soyadına göre sıralanır.The keys are sorted by Town, and then by LastName for records that have the same value for Town.

Şekil 5 -Bileşik anahtara göre bir dizin tablosu

Dizin tabloları, parçalı veriler üzerinde sorgu işlemlerini hızlandırabilir ve parça anahtarı karma olduğunda özellikle yararlıdır.Index tables can speed up query operations over sharded data, and are especially useful where the shard key is hashed. Sonraki şekilde parça anahtarının Müşteri Kimliği karması olduğu bir örnek gösterilmiştir.The next figure shows an example where the shard key is a hash of the Customer ID. Dizin tablosu, verileri karma olmayan değerlere göre düzenleyebilir (Şehir ve Soyadı) ve arama verisi olarak karma haline getirilmiş parça anahtarını sağlayabilir.The index table can organize data by the nonhashed value (Town and LastName), and provide the hashed shard key as the lookup data. Böylece uygulamanın belirli bir aralıktan veri alması gerekiyorsa veya karma olmayan anahtara göre veri getirmesi gerekiyorsa sürekli karma anahtarları hesaplaması gerekmez (bu pahalı bir işlemdir).This can save the application from repeatedly calculating hash keys (an expensive operation) if it needs to retrieve data that falls within a range, or it needs to fetch data in order of the nonhashed key. Örneğin "Redmond’da yaşayan tüm müşterileri bul" gibi bir sorgu, verilerin bütün bir blok halinde depolandığı dizin tablosunda eşleşen öğeler bulunarak hızlıca çözülebilir.For example, a query such as “Find all customers that live in Redmond” can be quickly resolved by locating the matching items in the index table, where they're all stored in a contiguous block. Ardından, dizin tablosunda depolanan parça anahtarları kullanılarak müşteri verilerine başvurular izlenir.Then, follow the references to the customer data using the shard keys stored in the index table.

Şekil 6 - Parçalı veriler için hızlı arama sağlayan bir dizin tablosu

Sorunlar ve dikkat edilmesi gerekenlerIssues and considerations

Bu düzenin nasıl uygulanacağına karar verirken aşağıdaki noktaları göz önünde bulundurun:Consider the following points when deciding how to implement this pattern:

  • İkincil dizinlerin bakım maliyeti önemli ölçüde fazla olabilir.The overhead of maintaining secondary indexes can be significant. Uygulamanızın kullandığı sorguları analiz etmeniz ve anlamanız gerekir.You must analyze and understand the queries that your application uses. Dizin tablolarını yalnızca düzenli olarak kullanılma olasılığı varsa oluşturun.Only create index tables when they're likely to be used regularly. Bir uygulamanın gerçekleştirmediği veya nadiren gerçekleştirdiği sorguları desteklemek için kurgusal dizin tabloları oluşturmayın.Don't create speculative index tables to support queries that an application doesn't perform, or performs only occasionally.

  • Bir dizin tablosunda veri çoğaltma yapılması depolama maliyetlerini ve verilerin birden çok kopyasını tutmak için gereken çabayı önemli ölçüde artırabilir.Duplicating data in an index table can add significant overhead in storage costs and the effort required to maintain multiple copies of data.

  • Bir dizin tablosunu orijinal verilere başvuruda bulunan normalleştirilmiş bir yapı olarak uygulamak, uygulamanın veri bulmak için iki arama işlemi gerçekleştirmesini gerektirir.Implementing an index table as a normalized structure that references the original data requires an application to perform two lookup operations to find data. İlk işlem, birincil anahtarı almak için dizin tablosunda arama yapar ve ikinci işlem de veri getirmek için birincil anahtarı kullanır.The first operation searches the index table to retrieve the primary key, and the second uses the primary key to fetch the data.

  • Bir sistem, çok büyük veri kümelerinde birden dizin tablosu içeriyorsa, dizin tabloları ve özgün veriler arasında tutarlılık sağlamak zor olabilir.If a system incorporates a number of index tables over very large data sets, it can be difficult to maintain consistency between index tables and the original data. Uygulamayı son tutarlılık modeline göre tasarlamak mümkün olabilir.It might be possible to design the application around the eventual consistency model. Örneğin veri eklemek, güncelleştirmek veya silmek için bir uygulama, sıraya bir ileti gönderebilir ve ayrı bir görevin bu işlemi yapmasına ve bu verilere zaman uyumsuz olarak başvuran dizin tablolarını tutmasına olanak verebilir.For example, to insert, update, or delete data, an application could post a message to a queue and let a separate task perform the operation and maintain the index tables that reference this data asynchronously. Son tutarlılık uygulama hakkında daha fazla bilgi için bkz. Veri tutarlılığı Temel Bilgileri.For more information about implementing eventual consistency, see the Data Consistency Primer.

    Microsoft Azure depolama tabloları aynı bölümde tutulan verilerde yapılan değişiklikler için işlem güncelleştirmelerini (varlık grubu işlemleri olarak adlandırılır) destekler.Microsoft Azure storage tables support transactional updates for changes made to data held in the same partition (referred to as entity group transactions). Bir olgu tablosu için verileri ve bir veya daha fazla dizin tablosunu aynı bölümde depolayabilirseniz, tutarlılık sağlanmasına yardımcı olması için bu özelliği kullanabilirsiniz.If you can store the data for a fact table and one or more index tables in the same partition, you can use this feature to help ensure consistency.

  • Dizin tabloları bölümlenmiş ya da parçalı olabilir.Index tables might themselves be partitioned or sharded.

Bu düzenin kullanılacağı durumlarWhen to use this pattern

Bir uygulamanın sıklıkla birincil (veya parçalı) anahtarı dışında bir anahtar kullanarak veri alması gerekiyorsa sorgu performansını artırmak için bu düzeni kullanın.Use this pattern to improve query performance when an application frequently needs to retrieve data by using a key other than the primary (or shard) key.

Bu düzen aşağıdaki durumlarda kullanışlı olmayabilir:This pattern might not be useful when:

  • Veriler geçicidir.Data is volatile. Bir dizin tablosu çok hızlı bir şekilde eskiyerek verimsizleşebilir veya tutulması, dizin tablosunu kullanarak yapılan tasarruflardan daha masraflı hale gelebilir.An index table can become out of date very quickly, making it ineffective or making the overhead of maintaining the index table greater than any savings made by using it.
  • Bir dizin tablosu için ikincil anahtar olarak seçilen alanlar fark gözetmez ve yalnızca küçük bir değerler kümesi (örneğin cinsiyet) olabilir.A field selected as the secondary key for an index table is nondiscriminating and can only have a small set of values (for example, gender).
  • Bir dizin tablosu için ikincil anahtar olarak seçilen alanın veri değerleri büyük oranda asimetriktir.The balance of the data values for a field selected as the secondary key for an index table are highly skewed. Örneğin, kayıtların % 90'ı alandaki aynı değeri içeriyorsa, bu alana göre veri aramak için bir dizin tablosunun oluşturulması ve bakımı verileri sırayla taramaya göre daha fazla ek yük oluşturabilir.For example, if 90% of the records contain the same value in a field, then creating and maintaining an index table to look up data based on this field might create more overhead than scanning sequentially through the data. Ancak, sorgular çok sık geri kalan %10 içinde bulunan değerleri hedefliyorsa, bu dizin yararlı olabilir.However, if queries very frequently target values that lie in the remaining 10%, this index can be useful. Uygulamanızın çalıştırdığı sorguları ve bu sorguların ne sıklıkla çalıştırıldığını bilmeniz gerekir.You should understand the queries that your application is performing, and how frequently they're performed.

ÖrnekExample

Azure depolama tabloları, bulutta çalışan uygulamalar için yüksek düzeyde ölçeklenebilir bir anahtar/değer veri deposu sağlar.Azure storage tables provide a highly scalable key/value data store for applications running in the cloud. Uygulamalar, veri değerlerini bir anahtarı belirterek depolar ve alır.Applications store and retrieve data values by specifying a key. Veri değerleri birden çok alan içerebilir, ancak veri öğelerinin yapısı, veri öğesini bir bayt dizisi olarak işleyen tablo depolaması için donuk yapıdadır.The data values can contain multiple fields, but the structure of a data item is opaque to table storage, which simply handles a data item as an array of bytes.

Azure depolama tabloları, parçalamayı da destekler.Azure storage tables also support sharding. Parçalama anahtarı bir bölüm anahtarı ve bir kayıt anahtarı olmak üzere iki öğe içerir.The sharding key includes two elements, a partition key and a row key. Aynı bölüm anahtarına sahip öğeler aynı bölümde (parça) saklanır ve öğeler, parça içindeki kayıt anahtarı sırasında depolanır.Items that have the same partition key are stored in the same partition (shard), and the items are stored in row key order within a shard. Tablo depolaması, bir bölüm içindeki bütün bir aralıkta kalan kayıt anahtarı değerlerinden veri alan sorguları gerçekleştirmek için en iyi duruma getirilmiştir.Table storage is optimized for performing queries that fetch data falling within a contiguous range of row key values within a partition. Azure tablolarında bilgi depolayan bulut uygulamaları oluşturuyorsanız, verilerinizi bu özelliğe göre yapılandırmalısınız.If you're building cloud applications that store information in Azure tables, you should structure your data with this feature in mind.

Örneğin, filmlerle ilgili bilgiler depolayan bir uygulama düşünün.For example, consider an application that stores information about movies. Bu uygulama, filmleri sıklıkla türe göre (aksiyon, belgesel, tarih, komedi, dram vb.) sorgular.The application frequently queries movies by genre (action, documentary, historical, comedy, drama, and so on). Türü bölüm anahtarı olarak kullanarak ve satır anahtarı olarak film adı belirterek aşağıda gösterildiği gibi her bir tür için bölümleri olan bir Azure tablosu oluşturabilirsiniz.You could create an Azure table with partitions for each genre by using the genre as the partition key, and specifying the movie name as the row key, as shown in the next figure.

Şekil 7 - Bir Azure tablosunda depolanan film verileri

Bu yaklaşım, uygulamanın filmleri başrol aktörüne göre de sorgulaması gerekiyorsa daha az etkili olur.This approach is less effective if the application also needs to query movies by starring actor. Bu durumda, bir dizin tablosu olarak davranan ayrı bir Azure tablosu oluşturabilirsiniz.In this case, you can create a separate Azure table that acts as an index table. Bölüm anahtarı aktör olur ve kayıt anahtarı da film adı olur.The partition key is the actor and the row key is the movie name. Her aktör için veriler ayrı bölümlerde depolanır.The data for each actor will be stored in separate partitions. Bir filmde birden fazla aktör varsa aynı film birden çok bölümden oluşur.If a movie stars more than one actor, the same movie will occur in multiple partitions.

Yukarıdaki çözüm bölümünde açıklanan ilk yaklaşımı kullanarak her bölümde tutulan değerlerdeki film verilerini çoğaltabilirsiniz.You can duplicate the movie data in the values held by each partition by adopting the first approach described in the Solution section above. Bununla birlikte, her filmin birkaç kez (her aktör için bir kez) çoğaltılması olasıdır. Bu nedenle (örneğin, diğer aktörler adları) en yaygın sorguları desteklemek için verileri kısmen normalleştirilmişten çıkarmak ve tür bölümlerinde tam bilgiyi bulmak için gereken bölüm anahtarını dahil ederek uygulamanın kalan diğer ayrıntıları almasına olanak vermek daha verimli olabilir.However, it's likely that each movie will be replicated several times (once for each actor), so it might be more efficient to partially denormalize the data to support the most common queries (such as the names of the other actors) and enable an application to retrieve any remaining details by including the partition key necessary to find the complete information in the genre partitions. Bu yaklaşım, Çözüm bölümündeki üçüncü seçenekte açıklanmıştır.This approach is described by the third option in the Solution section. Sonraki şekilde bu yaklaşım gösterilmiştir.The next figure shows this approach.

Şekil 8 - Film verileri için dizin tabloları olarak kullanılan aktör bölümleri

Bu düzen uygulanırken aşağıdaki düzenler ve yönergeler de yararlı olabilir:The following patterns and guidance might also be relevant when implementing this pattern:

  • Veri Tutarlılığı Temel Bilgileri.Data Consistency Primer. Dizin tablosunun dizinlediği veriler değiştiğinde dizin tablosuna bakım yapılmalıdır.An index table must be maintained as the data that it indexes changes. Bulutta, verileri değiştiren işlemin bir parçası olarak dizini güncelleştiren işlemleri gerçekleştirmek olası veya doğru olmayabilir.In the cloud, it might not be possible or appropriate to perform operations that update an index as part of the same transaction that modifies the data. Bu durumda, sonuçta tutarlı bir yaklaşım daha uygundur.In that case, an eventually consistent approach is more suitable. Son tutarlılıkla ilgili sorunlar hakkında bilgi sağlar.Provides information on the issues surrounding eventual consistency.
  • Parçalama düzeni.Sharding pattern. Dizin Tablosu düzeni, parça kullanarak bölümlenmiş verilerle birlikte sık kullanılır.The Index Table pattern is frequently used in conjunction with data partitioned by using shards. Parçalama düzeni, bir veri deposunu parça kümesine bölme hakkında daha fazla bilgi sağlar.The Sharding pattern provides more information on how to divide a data store into a set of shards.
  • Gerçekleştirilmiş Görünüm düzeni.Materialized View pattern. Verileri özetleyen sorguları desteklemek için veri dizini oluşturmak yerine verilerin gerçekleştirilmiş görünümünü oluşturmak daha uygun olabilir.Instead of indexing data to support queries that summarize data, it might be more appropriate to create a materialized view of the data. Veriler üzerinde önceden doldurulmuş görünümler oluşturarak verimli özet sorgularının nasıl destekleneceğini açıklar.Describes how to support efficient summary queries by generating prepopulated views over data.