Oracle'dan SQL Server'a ve SQL Server'dan Oracle'a Geçiş Kılavuzu - Pt. 2

Yayınlanan: 2022-03-11

Bu dizinin ilk bölümü, Oracle'dan SQL Server'a geçişler sırasında veya tam tersi sırasında karşılaşılabilecek tuzaklara odaklanarak, işlemlerin uygulanmasında Oracle Veritabanı ve Microsoft SQL Server arasındaki farkları tartıştı. Bu sonraki bölüm, Oracle-SQL Server ayrımında eşleşmeyen veya tamamen farklı bir anlama veya kullanıma sahip, yaygın olarak kullanılan bir dizi SQL sözdizimi öğesini kapsayacaktır.

Oracle'daki Diziler ve SQL Server'daki Kimlik Sütunları

Veritabanı topluluğunda iki kamp arasında uzun süredir devam eden bir ayrım var: doğal anahtarların yurtseverleri ve yapay (veya “vekil”) anahtarların savunucuları.

Ben kendim doğal anahtarları savunuyorum ama çoğu zaman kendimi bir nedenden dolayı vekiller yaratırken buluyorum. Ancak bu tartışmanın özünü bir kenara bırakarak, yapay anahtarlar oluşturmak için standart mekanizmalara bakalım: Oracle dizileri ve SQL Server kimlik sütunları.

Oracle dizisi, birinci sınıf bir veritabanı düzeyinde nesnedir. Buna karşılık, bir SQL Server kimlik sütunu, bir nesne değil, bir sütun türüdür.

Bir tablo anahtarı (genellikle birincil anahtar) oluşturmak için bir Oracle dizisi kullanıldığında, artacağı ve dolayısıyla benzersiz olacağı garanti edilir. Ama ardışık olması garanti değil . Aslında, iyi tasarlanmış uygulamalarda bile, bazı boşluklara sahip olma olasılığı yüksektir. Dolayısıyla hiçbir Oracle uygulaması, ardışık olmak için dizi tarafından oluşturulan değerlere asla güvenmemelidir.

Ayrıca, bir dizi bir Oracle veritabanının veri sözlüğü aracılığıyla yönetilir, bu nedenle her bir yedek anahtarı desteklemek için özel bir dizi oluşturmak çok kaynak tüketen (ve zahmetli) olacaktır. Tek bir dizi nesnesi, birden çok ve hatta tüm yedek anahtarı destekleyebilir.

Öte yandan, birden çok işlemin bir diziden NEXTVAL (bir sonraki artımlı değer) erişmesi gerektiğinde, dizi kritik, tek erişimli bir kaynak haline gelecektir. Tüm süreçleri katı bir şekilde sıralı hale getirerek, herhangi bir çok kanallı (tek veya çok sunuculu) uygulamayı uzun bekleme süreleri ve yüksek bellek/düşük CPU kullanımı ile tek iş parçacıklı bir sürece dönüştürecektir.

Bu tür uygulamalar gerçekten oluyor. Bu sorunun çözümü, söz konusu dizi nesnesini makul önbellek değeriyle tanımlamaktır; bu, tanımlı bir değer aralığının (100 veya 100 bin olabilir) bir çağrı işlemi için bir önbelleğe seçilmesi ve kullanıldığı şekilde veri sözlüğüne kaydedilmesidir. ve NEXTVAL her çağrıldığında veri sözlüğüne erişmeye gerek kalmadan bu özel işlem için kullanılabilir hale gelir.

Ancak, tüm önbelleğe alınan değerlerin kullanılması muhtemel olmadığı için boşlukların oluşmasının nedeni tam olarak budur. Aynı zamanda, paralel oturumlardaki birden çok işlemde, kaydedilen bazı sıra değerlerinin kronolojik olarak ters çevrilebileceği anlamına gelir. Bu tersine çevirme, bir sıra değeri sıfırlanmadıkça veya geriye kaydırılmadıkça tek bir işlem içinde gerçekleşemez. Ancak bu son senaryo, sorun aramak anlamına gelir: Gereksiz olmalıdır ve yanlış uygulanırsa, mükerrer değerler üretilmesine neden olabilir.

Bu nedenle, Oracle dizilerini kullanmanın tek doğru yolu, yedek anahtarların üretilmesidir: benzersiz olan ancak başka herhangi bir güvenilir kullanılabilir bilgiyi tutmadığı varsayılan anahtarlar.

SQL Server'da Kimlik Sütunları

SQL Server'dan ne haber? Oracle benzerlerine çok benzer işlevselliğe ve uygulamaya sahip diziler SQL Server 2012'de tanıtılmış olsa da, bunlar birinci sınıf bir teknik değildir. Diğer özellik eklemeleri gibi, Oracle'dan dönüşüm için anlamlıdırlar, ancak SQL Server'da sıfırdan yedek anahtarları uygularken IDENTITY çok daha iyi bir seçenektir.

IDENTITY , bir tablonun "alt" nesnesidir. Bir tablonun dışındaki hiçbir kaynağa erişmez ve kasıtlı olarak değiştirilmedikçe sıralı olması garanti edilir. Ve Oracle ile anlamsal uyumluluktan ziyade özellikle bu görev için tasarlanmıştır.

Oracle, 12.1 sürümünde IDENTITY işlevselliğini uyguladığında, daha önce onsuz nasıl yaptığını, neden şimdi uyguladığını ve SQL Server'ın en başından beri (Sybase SQL Server kökenlerinden) neden buna ihtiyaç duyduğunu merak etmek doğaldır.

Bunun nedeni, Oracle'ın her zaman bir kimlik anahtarı özelliğine sahip olmasıdır: ROWID veya UROWID veri tipine sahip ROWID sözde sütun. Bu değer sayısal değildir ( ROWID ve UROWID tescilli Oracle veri türleridir) ve bir veri kaydını benzersiz şekilde tanımlar.

SQL Server'ın IDENTITY farklı olarak, Oracle'ın ROWID kolayca değiştirilemez (sorgulanabilir, ancak eklenemez veya değiştirilemez) ve her Oracle tablosundaki her satır için arka planda oluşturulur. Ayrıca, bir Oracle veritabanındaki herhangi bir veri satırına erişmenin en verimli yolu, ROWID , bu nedenle bir performans optimizasyon tekniği olarak kullanılır. Son olarak, satır verilerinin düşük seviyeli depolanmasını etkin bir şekilde indekslediğinden, varsayılan sorgu çıktısı sıralama düzenini tanımlar.

Oracle'ın ROWID bu kadar önemliyse, SQL Server bunca yıl ve sürümler olmadan nasıl hayatta kaldı? IDENTITY sütunlarını birincil (vekil) anahtarlar olarak kullanarak.

Oracle ve SQL Server arasındaki dizin yapısı uygulamasındaki farkı not etmek önemlidir.

SQL Server'da, ilk dizin—birincil anahtar, çoğu zaman değil—kümelenir; bu, en yaygın olarak birincil veri dosyasındaki verilerin bu anahtar tarafından sıralandığı anlamına gelir. Oracle tarafında, kümelenmiş bir dizinin eşdeğeri, dizinle düzenlenmiş bir tablodur. Bu, Oracle'da, örneğin salt okunur arama tabloları için, yalnızca gerektiğinde, ara sıra kullanılan isteğe bağlı bir yapıdır.

Oracle'da ROWID kullanımına dayanan (veri tekilleştirme gibi) tüm tasarım desenleri, SQL Server'a geçiş yapılırken IDENTITY sütunlarına dayalı olarak uygulanmalıdır.

SQL Server'da IDENTITY kullanımından Oracle'da IDENTITY kullanımına geçiş, işlevsel olarak doğru kod üretebilirken, optimal değildir, çünkü Oracle tarafında ROWID çok daha verimli performans gösterecektir.

Aynısı, Oracle dizilerini SQL Server'a taşımak için basit bir SQL sözdizimi dönüşümü yaparken de geçerlidir: Kod çalışacaktır, ancak IDENTITY kullanmak hem kod basitliği hem de performans açısından en çok tercih edilen seçenektir.

Microsoft SQL Server'da Filtrelenmiş Dizinler

Yıllar önce, Microsoft SQL Server 2008, onu gerçekten birinci sınıf bir kurumsal veritabanına dönüştüren bir dizi önemli özelliği tanıttı. Günümü bir kereden fazla kurtaran biri filtrelenmiş indeksler oldu.

Filtre uygulanmış bir dizin, WHERE yan tümcesine sahip kümelenmemiş bir dizindir (yani, kendi veri dosyası olarak var olan). Bu, dizin dosyasının yalnızca yan tümce ile ilgili veri kayıtlarını içerdiği anlamına gelir. Filtrelenmiş dizinlerden tam olarak yararlanmak için, bir veri kümesi döndürürken gerekli olan tüm sütunları listeleyen bir INCLUDE yan tümcesine de sahip olmalıdır. Sorgunuz gerekli tüm veri noktalarını içeren belirli bir filtre uygulanmış dizini kullanmak üzere optimize edildiğinde, veritabanı motorunun birincil tablo veri dosyasına bakmadan yalnızca (küçük) bir dizin dosyasına erişmesi gerekir.

Bu, birkaç yıl önce terabayt boyutunda bir masayla çalışırken benim için özellikle değerliydi. Söz konusu müşterinin, herhangi bir zamanda aktif olan kayıtların yalnızca yüzde birlik bir kısmına sıklıkla erişmesi gerekiyordu. Bu erişimin ilk uygulaması (son kullanıcı UI eylemleriyle tetiklenir) yalnızca acı verecek kadar yavaş değil, aynı zamanda kullanılamaz durumdaydı. Gerekli INCLUDE s ile filtrelenmiş bir dizin eklediğimde, bu bir milisaniyenin altında bir arama haline geldi. Bu optimizasyon görevi için harcadığım zaman sadece bir saatti.

Elbette, filtrelenmiş dizinlerin bazı sınırlamaları vardır. LOB sütunlarını içeremezler, dizinlerin kendilerinin WHERE tümcelerinin hangi koşulları içerebileceği konusunda sınırlamalar vardır ve bunlar bir veritabanının depolama ayak izine eklenir. Ancak, bu parametrelere uyan bir kullanım durumu sağlandığında, depolama takasları, filtrelenmiş dizinlerin sağlayabileceği önemli performans artışına kıyasla genellikle oldukça küçüktür.

Oracle Veritabanındaki Filtrelenmiş İndeksler Nedir?

Daha sonra kendimi bir Fortune 500 şirketinde SQL Server'dan Oracle'a geçiş projesinde geliştirici/DBA olarak büyük bir ekipte buldum. Kaynak veritabanını çevreleyen kod (SQL Server 2008), dönüştürmeyi zorunlu kılan yetersiz performansla yetersiz bir şekilde uygulandı: Günlük arka uç eşitleme işi 23 saatten uzun sürüyordu. Filtrelenmiş dizinleri yoktu, ancak yeni Oracle 11g sisteminde, filtrelenmiş dizinlerin çok faydalı olacağı birçok durum gördüm. Ancak Oracle 11g'nin filtrelenmiş dizinleri yok!

En son Oracle 18c'de filtrelenmiş dizinler de uygulanmaz.

Ancak teknik uzmanlar olarak görevimiz elimizdekileri en iyi şekilde kullanmaktır. Böylece Oracle 11g sistemimde filtrelenmiş dizinlerin eşdeğerini uyguladım (ve daha sonra 12c'de kullandığım tekniğin aynısı). Fikir, Oracle'ın NULL nasıl ele aldığına dayanmaktadır ve Oracle'ın herhangi bir sürümünde kullanılabilir.

Oracle, NULL değerine normal verilerle aynı şekilde davranmaz. Oracle'da bir NULL hiçbir şey değildir - mevcut değildir. Sonuç olarak, dizinlenmiş sütununuzu NULL olarak tanımlarsanız ve NULLABLE olmayan değerlerle arama yapıyorsanız, dizin veri dosyanız yalnızca ilgilenilen kayıtları içerecektir. Oracle dizin tanımında INCLUDE yan tümcesi bulunmadığından, bir sonuç kümesine dahil edilmesi gereken tüm sütunlarla bir bileşik dizin oluşturmanız gerekir. (Bu teknik, SQL Server'ın INCLUDE yan tümcesine kıyasla biraz ek yüke sahiptir, ancak oldukça önemsizdir.)

Böyle bir geçici çözüm uygulaması bir sınırlama getirir: Önde gelen dizin sütunu NULL s'ye izin vermelidir ve bu nedenle tablonun birincil anahtarı olamaz. Ancak, bu performans optimizasyon yöntemini desteklemek için özel olarak oluşturulmuş türetilmiş veya hesaplanmış bir sütun olabilir . Bir anlamda, dizinin önde gelen sütunu mantıksal olarak ikilidir: aramanıza dahil edilen veriler için NULL olmayan değerler ve "görünmez" olması gereken tüm veriler için NULL değerler.

SQL Server filtrelenmiş dizin mantığını Oracle'a geçirmedeki diğer olası seçenek, bir dizini (veya tabloyu tam olarak) bölümlenmiş olarak uygulamaktır. Bu durumda, veritabanı motoru tarafından yalnızca ilgili dizin bölümüne erişilecektir; sağlanan sorguların WHERE tümcelerindeki tam bölümleme koşulu kullanılarak doğru şekilde uygulanması sağlanır.

Bu, nispeten statik veriler üzerinde büyük ölçekte bile iyi çalışır, ancak sık değişen verilere uygulandığında DBA ekibine yüksek bakım yükü getirebilir. Zaman merkezli bir uygulamada bugünün verilerine erişimi optimize ederken buna bir örnek verilebilir: DBA ekibinin bölümleri günlük olarak yeniden tanımlaması gerekecektir. Bu yeniden tanımlama, bir gecelik bakım işinde yazılabilir olsa da, sisteminizi daha karmaşık hale getirir ve yeni olası sistemik arıza noktalarını ortaya çıkarır.

Bu nedenle, SQL Server filtrelenmiş dizin mantığının Oracle'a taşınması gerektiğinde çok spesifik ve dikkatli olunmalıdır.

Dönüşümler Nasıl İşlenir?

Oracle'dan SQL Server'a geçişle, filtrelenmiş dizinleri kullanarak optimizasyon fırsatlarını arayın. Oracle'da filtrelenmiş dizinler görmezsiniz, ancak NULL değerleri içeren dizinler görebilirsiniz. Bunları olduğu gibi kopyalamayın: Dönüşümünüzde performans artışı ve tasarım iyileştirmesi elde edebileceğiniz en iyi yer burası olabilir.

SQL Server'dan Oracle'a geçişler için, filtrelenmiş dizinler görürseniz, karşılık gelen Oracle kodunuzdaki performans darboğazından nasıl kaçınacağınızı araştırın. Kaynak uygulamada filtrelenmiş dizinlerin sağladığı eksik performans artışını telafi etmek için veri akışını nasıl yeniden tasarlayabileceğinizi görün.

SQL Server'dan Oracle'a / Oracle'dan SQL Server'a Geçiş Zorlukları Ortadan Kaldırıldı

Oracle ve SQL Server arasında her iki yöndeki geçiş projeleri için, ilgili mekanikleri daha derinden anlamak önemlidir. İlgili veritabanlarının (Oracle 18c ve Microsoft SQL Server 2017*) güncel sürümleri, birbirinin işlevselliğinin sözcüksel eşdeğerlerini (örneğin, diziler ve kimlikte) içerdiğinde, bu kolay bir kazanç gibi görünebilir. Ancak iyi bir tasarımı bir RDBMS'de doğrudan diğerine kopyalamak, gereksiz yere karmaşık ve düşük performans gösteren bir koda neden olabilir.

Bu serinin sonraki ve son bölümünde, okuma tutarlılığı ve geçiş araçlarının kullanımını ele alacağım. Bizi izlemeye devam edin!

* SQL Server 2019 (veya “15.x”), yaygın kurumsal benimseme için yeterince uzun sürmedi.