SQL Server setara dengan Oracle MENGGUNAKAN klausa INDEX

9

Apakah ada SQL Server 2008 yang setara dengan klausa MENGGUNAKAN INDEKS di Oracle? Khusus untuk konstruk:

CREATE TABLE c(c1 INT, c2 INT);
CREATE INDEX ci ON c (c1, c2);
ALTER TABLE c ADD CONSTRAINT cpk PRIMARY KEY (c1) USING INDEX ci;

Dalam Dokumentasi Sql Server tentang Indeks Unik itu menyatakan (penekanan ditambahkan):

Indeks unik diimplementasikan dengan cara berikut:

Kendala UTAMA atau kendala UNIK

Saat Anda membuat batasan PRIMARY KEY, indeks berkerumun unik pada kolom atau kolom secara otomatis dibuat jika indeks berkerumun pada tabel belum ada dan Anda tidak menentukan indeks nonclustered unik . Kolom kunci utama tidak dapat mengizinkan nilai NULL.

Yang tampaknya menyiratkan bahwa ada cara menentukan indeks apa yang harus digunakan untuk Kunci Utama.

nik
sumber
Cukup tentukan PK bersama-sama dengan tabel. create table c (c1 int not null primary key, c2 int)
a_horse_with_no_name
Ini bagian "membuat PK menggunakan indeks bernama" yang saya tertarik.
nik
Tidak, tidak ada cara untuk melakukan itu. Kunci utama adalah batasan dan indeks. Dalam apa yang Anda berikan kunci utama secara default akan menjadi indeks berkerumun unik. Yang mana akan membuat indeks yang didefinisikan lainnya duplikat kecuali Anda memasukkan c1 dan c2 dalam klausa where.
Aaron

Jawaban:

7

Apakah ada SQL Server 2008 yang setara dengan klausa MENGGUNAKAN INDEKS di Oracle?

Tidak. Ketika Anda membuat kunci utama atau batasan unik dalam SQL Server, indeks unik untuk mendukung batasan itu dibuat secara otomatis, dengan kunci yang sama.

Yang tampaknya menyiratkan bahwa ada cara menentukan indeks apa yang harus digunakan untuk Kunci Utama.

Tidak. Dokumentasi hanya berusaha menjelaskan apakah indeks pendukung otomatis akan dibuat sebagai clustered atau nonclustered, jika Anda tidak menentukan. Ini membingungkan, saya setuju.

Untuk memperjelas, saat Anda menambahkan batasan kunci utama ke tabel yang ada tanpa menyatakan preferensi, indeks pendukung akan dikelompokkan jika tidak ada indeks berkerumun di meja yang sudah ada sebelumnya. Indeks pendukung akan dibuat sebagai nonclustered jika sudah ada indeks berkerumun

Anda dapat secara khusus meminta kunci primer yang dikelompokkan atau tidak menggunakan menggunakan: PRIMARY KEY CLUSTEREDatau PRIMARY KEY NONCLUSTERED.

Dalam keadilan, dokumentasi jauh lebih jelas tentang subjek di:

table_constraint (Transact-SQL)

Paul White 9
sumber
5

Sintaks SQL Server untuk membuat indeks berkerumun yang juga merupakan kunci utama adalah:

CREATE TABLE dbo.c
(
    c1 INT NOT NULL, 
    c2 INT NOT NULL,
    CONSTRAINT PK_c
    PRIMARY KEY CLUSTERED (c1, c2)
);

Sejauh komentar Anda: "membuat PK menggunakan indeks bernama", kode di atas akan menghasilkan indeks kunci utama yang dinamai "PK_c".

Kunci primer dan kunci pengelompokan tidak harus kolom yang sama. Anda dapat mendefinisikannya secara terpisah. Pada contoh di atas, ubah CLUSTEREDkata kunci menjadi NONCLUSTERED, lalu tambahkan indeks berkerumun menggunakan CREATE INDEXsintaksis:

CREATE TABLE dbo.c
(
    c1 INT,
    c2 INT,
    CONSTRAINT PK_c
    PRIMARY KEY NONCLUSTERED (c1, c2)
);

CREATE CLUSTERED INDEX CX_c ON dbo.c (c2);

Dalam SQL Server indeks berkerumun adalah tabel, mereka satu-dan-sama. Indeks berkerumun mendefinisikan urutan logis dari baris yang disimpan dalam tabel. Dalam contoh pertama saya, baris disimpan dalam urutan nilai-nilai c1dan c2kolom. Karena kunci pengelompokan juga didefinisikan sebagai kunci utama, kombinasi dari c1dan c2harus unik untuk seluruh tabel.

Dalam contoh kedua, kunci utama terdiri dari kolom c1dan c2, namun kunci pengelompokan hanya c2kolom. Karena saya tidak menentukan UNIQUEatribut dalam CREATE INDEXpernyataan, kunci pengelompokan ( c2) tidak harus unik di seluruh tabel. "Uniquifier" akan secara otomatis dibuat oleh SQL Server dan ditambahkan ke nilai-nilai di c2kolom untuk membuat kunci pengelompokan. Kunci pengelompokan ini, karena sekarang unik, kemudian akan digunakan sebagai id baris dalam indeks lain yang dibuat di tabel.

Untuk membuktikan kunci pengelompokan mengontrol tata letak baris dalam penyimpanan, Anda dapat menggunakan fungsi tidak berdokumen fn_PhysLocCracker(%%PHYSLOC%%),. Kode berikut menunjukkan baris diletakkan pada disk sesuai urutan c2kolom, yang telah saya definisikan sebagai kunci pengelompokan:

USE tempdb;

CREATE TABLE dbo.PKTest
(
    c1 INT NOT NULL
    , c2 INT NOT NULL
    , c3 VARCHAR(256) NOT NULL
);

ALTER TABLE PKTest 
ADD CONSTRAINT PK_PKTest 
PRIMARY KEY NONCLUSTERED (c1, c2);

CREATE CLUSTERED INDEX CX_PKTest 
ON dbo.PKTest(c2);

TRUNCATE TABLE dbo.PKTest;

INSERT INTO dbo.PKTest (c1, c2, c3)
SELECT TOP(25) o1.object_id / o2.object_id, o2.object_id, o1.name + '.' + o2.name
FROM sys.objects o1
    , sys.objects o2
WHERE o1.object_id >0 
    and o2.object_id > 0;

SELECT plc.file_id
    , plc.page_id
    , plc.slot_id
    , pk.*
FROM dbo.PKTest pk
CROSS APPLY fn_PhysLocCracker(%%PHYSLOC%%) plc;

Hasil dari tempdb saya , adalah:

masukkan deskripsi gambar di sini

Pada gambar di atas, tiga kolom pertama adalah output dari fn_PhysLocCrackerfungsi, yang menunjukkan urutan fisik baris pada disk. Anda dapat melihat slot_idnilai meningkatkan kunci-langkah dengan c2nilai, yang merupakan kunci pengelompokan. Indeks kunci utama menyimpan baris dalam urutan yang berbeda, yang dapat dilihat dengan memaksa SQL Server untuk mengembalikan hasil dari pemindaian kunci utama:

SELECT pkt.c1
    , pkt.c2
FROM dbo.PKTest pkt WITH (INDEX = PK_PKTest, FORCESCAN);

Catatan, saya tidak menggunakan ORDER BYklausa dalam pernyataan di atas karena saya mencoba untuk menunjukkan urutan item dalam indeks kunci utama.

Output dari query di atas adalah:

masukkan deskripsi gambar di sini

Melihat ke fn_PhysLocCrackerfungsi, kita dapat melihat urutan fisik dari indeks kunci primer.

SELECT plc.file_id
    , plc.page_id
    , plc.slot_id
    , pkt.c1
    , pkt.c2
FROM dbo.PKTest pkt WITH (INDEX = PK_PKTest, FORCESCAN)
CROSS APPLY fn_PhysLocCracker(%%PHYSLOC%%) plc;

Karena kita secara eksklusif membaca dari indeks itu sendiri, yaitu tidak ada kolom di luar indeks yang direferensikan dalam kueri, %%PHYSLOC%%nilai - nilai mewakili halaman dalam indeks itu sendiri.

Hasil:

masukkan deskripsi gambar di sini

Max Vernon
sumber