Pertama-tama, permintaan maaf atas jawaban yang begitu panjang, karena saya merasa masih ada banyak kebingungan ketika orang berbicara tentang istilah seperti susunan, susunan urutan, halaman kode, dll.
Dari BOL :
Kumpulan di SQL Server menyediakan aturan penyortiran, kasus, dan properti sensitivitas aksen untuk data Anda . Koleksi yang digunakan dengan tipe data karakter seperti char dan varchar mendiktekan halaman kode dan karakter terkait yang dapat direpresentasikan untuk tipe data tersebut. Apakah Anda menginstal contoh baru dari SQL Server, mengembalikan cadangan database, atau menghubungkan server ke database klien, penting bahwa Anda memahami persyaratan lokal, urutan penyortiran, dan case dan sensitivitas aksen dari data yang Anda akan bekerja dengan .
Ini berarti bahwa Collation sangat penting karena menetapkan aturan tentang bagaimana string karakter data diurutkan dan dibandingkan.
Catatan: Info lebih lanjut tentang COLLATIONPROPERTY
Sekarang mari kita pahami perbedaannya ......
Berjalan di bawah T-SQL:
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
Hasilnya adalah:
Melihat hasil di atas, satu-satunya perbedaan adalah Urutan Urutan antara 2 pemeriksaan. Tapi itu tidak benar, yang dapat Anda lihat mengapa seperti di bawah ini:
Tes 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
Hasil Uji 1:
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.
Dari hasil di atas kita dapat melihat bahwa kita tidak dapat secara langsung membandingkan nilai pada kolom dengan susunan berbeda, Anda harus menggunakan COLLATE
untuk membandingkan nilai kolom.
UJI 2:
Perbedaan utama adalah kinerja, seperti yang ditunjukkan oleh Erland Sommarskog pada diskusi ini di msdn .
--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')
--- Buat Indeks pada kedua tabel
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)
--- Jalankan kueri
DBCC FREEPROCCACHE
GO
SELECT Comments FROM Table_Latin1_General_CI_AS WHERE Comments = 'kin_test1'
GO
--- Ini akan memiliki Konversi IMPLICIT
--- Jalankan kueri
DBCC FREEPROCCACHE
GO
SELECT Comments FROM Table_SQL_Latin1_General_CP1_CI_AS WHERE Comments = 'kin_test1'
GO
--- Ini TIDAK akan memiliki Konversi IMPLICIT
Alasan untuk konversi implisit adalah karena, saya memiliki database & Server collation saya sebagai SQL_Latin1_General_CP1_CI_AS
dan tabel Table_Latin1_General_CI_AS memiliki kolom Komentar didefinisikan VARCHAR(50)
dengan COLLATE Latin1_General_CI_AS , jadi selama pencarian SQL Server harus melakukan konversi IMPLICIT.
Tes 3:
Dengan pengaturan yang sama, sekarang kita akan membandingkan kolom varchar dengan nilai nvarchar untuk melihat perubahan dalam rencana eksekusi.
- jalankan kueri
DBCC FREEPROCCACHE
GO
SELECT Comments FROM Table_Latin1_General_CI_AS WHERE Comments = (SELECT N'kin_test1' COLLATE Latin1_General_CI_AS)
GO
- jalankan kueri
DBCC FREEPROCCACHE
GO
SELECT Comments FROM Table_SQL_Latin1_General_CP1_CI_AS WHERE Comments = N'kin_test1'
GO
Perhatikan bahwa permintaan pertama dapat melakukan pencarian Indeks tetapi harus melakukan konversi implisit sementara yang kedua melakukan pemindaian Indeks yang terbukti tidak efisien dalam hal kinerja ketika akan memindai tabel besar.
Kesimpulan:
- Semua tes di atas menunjukkan bahwa memiliki susunan yang benar sangat penting untuk instance server database Anda.
SQL_Latin1_General_CP1_CI_AS
SQL collation dengan aturan yang memungkinkan Anda untuk mengurutkan data untuk unicode dan non-unicode berbeda.
- SQL collation tidak akan dapat menggunakan Indeks ketika membandingkan data unicode dan non-unicode seperti yang terlihat dalam tes di atas bahwa ketika membandingkan data nvarchar dengan data varchar, ia melakukan pemindaian indeks dan tidak mencari.
Latin1_General_CI_AS
adalah susunan Windows dengan aturan yang memungkinkan Anda untuk mengurutkan data untuk unicode dan non-unicode adalah sama.
- Windows collation masih dapat menggunakan Index (Index seek dalam contoh di atas) ketika membandingkan data unicode dan non-unicode tetapi Anda melihat sedikit penalti kinerja.
- Sangat merekomendasikan untuk membaca jawaban Erland Sommarskog + item terhubung yang telah ditunjuknya.
Ini akan memungkinkan saya untuk tidak memiliki masalah dengan tabel #temp, tetapi apakah ada jebakan?
Lihat jawaban saya di atas.
Apakah saya akan kehilangan fungsionalitas atau fitur apa pun dengan tidak menggunakan susunan SQL 2008 "terkini"?
Itu semua tergantung pada fungsi / fitur apa yang Anda maksud. Collation menyimpan dan menyortir data.
Bagaimana ketika kita pindah (misalnya dalam 2 tahun) dari 2008 ke SQL 2012? Apakah saya akan memiliki masalah? Apakah saya akan dipaksa untuk pergi ke Latin1_General_CI_AS?
Tidak bisa menjamin! Karena hal-hal mungkin berubah dan selalu baik untuk sejalan dengan saran Microsoft + Anda harus memahami data Anda dan jebakan yang saya sebutkan di atas. Lihat juga item ini dan item terhubung ini .
Saya membaca bahwa beberapa skrip DBA melengkapi deretan basis data lengkap, dan kemudian menjalankan skrip sisipkan ke dalam basis data dengan susunan baru - saya sangat takut dan waspada terhadap hal ini - apakah Anda akan merekomendasikan melakukan ini?
Saat Anda ingin mengubah susunan, maka skrip seperti itu berguna. Saya menemukan diri saya mengubah susunan basis data agar sesuai dengan susunan server berkali-kali dan saya memiliki beberapa skrip yang melakukannya dengan cukup rapi. Beri tahu saya jika Anda membutuhkannya.
Referensi :