Her şeyden önce, böyle uzun bir cevap için özür dilerim, çünkü insanlar harmanlama, sıralama düzeni, kod sayfası vb. Terimler hakkında konuştuğunda hala çok fazla karışıklık olduğunu hissediyorum.
Gönderen BOL :
SQL Server'daki harmanlamalar , verileriniz için sıralama kuralları, büyük / küçük harf duyarlılığı ve aksan duyarlılığı özellikleri sağlar . Char ve varchar gibi karakter veri türleriyle kullanılan harmanlamalar, kod sayfasını ve bu veri türü için temsil edilebilecek karşılık gelen karakterleri belirler. SQL Server'ın yeni bir örneğini yüklüyor, veritabanı yedeklemesini geri yüklüyor veya sunucuyu istemci veritabanlarına bağlarken, çalışacağınız verilerin yerel gereksinimlerini, sıralama düzenini ve büyük / küçük harf duyarlılığını anlamanız önemlidir. .
Bu, Harmanlama'nın, verilerin karakter dizilerinin nasıl sıralandığı ve karşılaştırıldığı ile ilgili kuralları belirlediği için çok önemli olduğu anlamına gelir.
Not: COLLATIONPROPERTY hakkında daha fazla bilgi
Şimdi önce farklılıkları anlayalım ......
T-SQL altında çalışıyor:
SELECT *
FROM::fn_helpcollations()
WHERE NAME IN (
'SQL_Latin1_General_CP1_CI_AS'
,'Latin1_General_CI_AS'
)
GO
SELECT 'SQL_Latin1_General_CP1_CI_AS' AS 'Collation'
,COLLATIONPROPERTY('SQL_Latin1_General_CP1_CI_AS', 'CodePage') AS 'CodePage'
,COLLATIONPROPERTY('SQL_Latin1_General_CP1_CI_AS', 'LCID') AS 'LCID'
,COLLATIONPROPERTY('SQL_Latin1_General_CP1_CI_AS', 'ComparisonStyle') AS 'ComparisonStyle'
,COLLATIONPROPERTY('SQL_Latin1_General_CP1_CI_AS', 'Version') AS 'Version'
UNION ALL
SELECT 'Latin1_General_CI_AS' AS 'Collation'
,COLLATIONPROPERTY('Latin1_General_CI_AS', 'CodePage') AS 'CodePage'
,COLLATIONPROPERTY('Latin1_General_CI_AS', 'LCID') AS 'LCID'
,COLLATIONPROPERTY('Latin1_General_CI_AS', 'ComparisonStyle') AS 'ComparisonStyle'
,COLLATIONPROPERTY('Latin1_General_CI_AS', 'Version') AS 'Version'
GO
Sonuçlar şöyle olacaktır:
Yukarıdaki sonuçlara bakıldığında, tek fark 2 harmanlama arasındaki Sıralama Düzeni'dir.Ancak bu doğru değil, nedenini aşağıdaki gibi görebilirsiniz:
Test 1:
--Clean up previous query
IF OBJECT_ID('Table_Latin1_General_CI_AS') IS NOT NULL
DROP TABLE Table_Latin1_General_CI_AS;
IF OBJECT_ID('Table_SQL_Latin1_General_CP1_CI_AS') IS NOT NULL
DROP TABLE Table_SQL_Latin1_General_CP1_CI_AS;
-- Create a table using collation Latin1_General_CI_AS
CREATE TABLE Table_Latin1_General_CI_AS (
ID INT IDENTITY(1, 1)
,Comments VARCHAR(50) COLLATE Latin1_General_CI_AS
)
-- add some data to it
INSERT INTO Table_Latin1_General_CI_AS (Comments)
VALUES ('kin_test1')
INSERT INTO Table_Latin1_General_CI_AS (Comments)
VALUES ('Kin_Tester1')
-- Create second table using collation SQL_Latin1_General_CP1_CI_AS
CREATE TABLE Table_SQL_Latin1_General_CP1_CI_AS (
ID INT IDENTITY(1, 1)
,Comments VARCHAR(50) COLLATE SQL_Latin1_General_CP1_CI_AS
)
-- add some data to it
INSERT INTO Table_SQL_Latin1_General_CP1_CI_AS (Comments)
VALUES ('kin_test1')
INSERT INTO Table_SQL_Latin1_General_CP1_CI_AS (Comments)
VALUES ('Kin_Tester1')
--Now try to join both tables
SELECT *
FROM Table_Latin1_General_CI_AS LG
INNER JOIN Table_SQL_Latin1_General_CP1_CI_AS SLG ON LG.Comments = SLG.Comments
GO
Test 1'in Sonuçları:
Msg 468, Level 16, State 9, Line 35
Cannot resolve the collation conflict between "SQL_Latin1_General_CP1_CI_AS" and "Latin1_General_CI_AS" in the equal to operation.
Yukarıdaki sonuçlardan, farklı harmanlamalara sahip sütunlardaki değerleri doğrudan COLLATE
karşılaştıramayacağımızı, sütun değerlerini karşılaştırmak için kullanmanız gerektiğini görebiliriz.
TEST 2:
Erland Sommarskog'un msdn hakkındaki bu tartışmada belirttiği gibi büyük fark performanstır .
--Clean up previous query
IF OBJECT_ID('Table_Latin1_General_CI_AS') IS NOT NULL
DROP TABLE Table_Latin1_General_CI_AS;
IF OBJECT_ID('Table_SQL_Latin1_General_CP1_CI_AS') IS NOT NULL
DROP TABLE Table_SQL_Latin1_General_CP1_CI_AS;
-- Create a table using collation Latin1_General_CI_AS
CREATE TABLE Table_Latin1_General_CI_AS (
ID INT IDENTITY(1, 1)
,Comments VARCHAR(50) COLLATE Latin1_General_CI_AS
)
-- add some data to it
INSERT INTO Table_Latin1_General_CI_AS (Comments)
VALUES ('kin_test1')
INSERT INTO Table_Latin1_General_CI_AS (Comments)
VALUES ('kin_tester1')
-- Create second table using collation SQL_Latin1_General_CP1_CI_AS
CREATE TABLE Table_SQL_Latin1_General_CP1_CI_AS (
ID INT IDENTITY(1, 1)
,Comments VARCHAR(50) COLLATE SQL_Latin1_General_CP1_CI_AS
)
-- add some data to it
INSERT INTO Table_SQL_Latin1_General_CP1_CI_AS (Comments)
VALUES ('kin_test1')
INSERT INTO Table_SQL_Latin1_General_CP1_CI_AS (Comments)
VALUES ('kin_tester1')
--- Her iki tabloda da Dizin Oluştur
CREATE INDEX IX_LG_Comments ON Table_Latin1_General_CI_AS(Comments)
go
CREATE INDEX IX_SLG_Comments ON Table_SQL_Latin1_General_CP1_CI_AS(Comments)
--- Sorguları çalıştırın
DBCC FREEPROCCACHE
GO
SELECT Comments FROM Table_Latin1_General_CI_AS WHERE Comments = 'kin_test1'
GO
--- Bu IMPLICIT Dönüşümü olacak
--- Sorguları çalıştırın
DBCC FREEPROCCACHE
GO
SELECT Comments FROM Table_SQL_Latin1_General_CP1_CI_AS WHERE Comments = 'kin_test1'
GO
--- Bunun IMPLICIT Dönüşümü YOKTUR
Ben hem benim veritabanı ve Sunucu harmanlamayı çünkü Örtülü dönüşüm için nedenidir SQL_Latin1_General_CP1_CI_AS
ve masa Table_Latin1_General_CI_AS sütun vardır Yorumlar olarak tanımlanan VARCHAR(50)
ile HARMANLA Latin1_General_CI_AS nedenle SQL Server bir IMPLICIT dönüşüm yapmak zorunda araması sırasında,.
Test 3:
Aynı kurulumla, şimdi yürütme planlarındaki değişiklikleri görmek için varchar sütunlarını nvarchar değerleriyle karşılaştıracağız.
- sorguyu çalıştır
DBCC FREEPROCCACHE
GO
SELECT Comments FROM Table_Latin1_General_CI_AS WHERE Comments = (SELECT N'kin_test1' COLLATE Latin1_General_CI_AS)
GO
- sorguyu çalıştır
DBCC FREEPROCCACHE
GO
SELECT Comments FROM Table_SQL_Latin1_General_CP1_CI_AS WHERE Comments = N'kin_test1'
GO
İlk sorgunun Dizin araması yapabildiğini, ancak İkincil dönüşüm yapması gerektiğini, ikincisinin ise büyük tabloları tarayacağı zaman performans açısından verimsiz olduğunu kanıtlayan bir Dizin taraması gerçekleştirdiğini unutmayın.
Sonuç:
- Yukarıdaki testlerin tümü, doğru harmanlamaya sahip olmanın veritabanı sunucusu örneğiniz için çok önemli olduğunu göstermektedir.
SQL_Latin1_General_CP1_CI_AS
unicode ve unicode olmayanlar için verileri sıralamanıza izin veren kurallara sahip bir SQL harmanlaması farklıdır.
- SQL harmanlama, yukarıdaki testlerde görüldüğü gibi unicode ve unicode olmayan verileri karşılaştırırken Dizin'i kullanamaz, nvarchar verilerini varchar verileriyle karşılaştırırken Dizin taraması yapar ve aramaz.
Latin1_General_CI_AS
unicode ve unicode olmayanlar için verileri sıralamanıza izin veren kurallara sahip bir Windows harmanlaması aynıdır.
- Windows harmanlama, unicode ve unicode olmayan verileri karşılaştırırken yine de Index'i (yukarıdaki örnekte Index search) kullanabilir, ancak hafif bir performans cezası görürsünüz.
- Erland Sommarskog cevap + işaret ettiği bağlantı öğelerini okumanızı tavsiye ederim.
Bu, #temp tablolarıyla ilgili sorun yaşamama izin verecek, ancak tuzaklar var mı?
Yukarıdaki cevabımı gör.
SQL 2008'in "geçerli" harmanlamasını kullanmadan herhangi bir işlevsellik veya özelliği kaybedebilir miyim?
Her şey hangi işlev / özelliklere başvurduğunuza bağlıdır. Harmanlama, verilerin saklanması ve sıralanmasıdır.
2008'den SQL 2012'ye geçtiğimizde (örneğin 2 yıl içinde) ne olacak? O zaman sorun yaşayacak mıyım? Bir noktada Latin1_General_CI_AS'a gitmek zorunda kalır mıyım?
Kefil olamaz! İşler değişebileceğinden ve Microsoft'un önerisiyle aynı çizgide olmak her zaman iyi olduğundan, verilerinizi ve yukarıda bahsettiğim tuzakları anlamanız gerekir. Ayrıca buna ve bu bağlantı öğelerine bakın.
Bazı DBA'nın komut dosyasının tam veritabanlarının satırlarını tamamladığını okudum ve sonra ekleme komut dosyasını yeni harmanlama ile veritabanına çalıştırıyorum - Çok korkuyorum ve bundan sakınıyorum - bunu tavsiye eder misiniz?
Harmanlamayı değiştirmek istediğinizde, bu tür komut dosyaları yararlı olur. Kendimi sunucu harmanlama birçok kez sunucu harmanlama maç için değişen bulduk ve oldukça düzgün yapan bazı komut dosyaları var. İhtiyacınız olursa bana bildirin.
Referanslar :