Daftar indeks dan batasan

10

Saya melihat database SQL Server untuk aplikasi yang saya warisi. Saya belum melihat ke SQL Server selama kurang lebih 10 tahun, jadi tolong bersamaku.

Tabel database yang saya lihat memiliki bigint NOT NULLkolom bernama id, namun, ketika saya memeriksa kendala, saya tidak melihat, dan hal yang sama berlaku untuk semua tabel database.

Apakah saya benar dengan berasumsi bahwa tidak ada kunci primer & tidak ada pengindeksan (berkerumun atau nonclustered) pada tabel ini?

Saya menjalankan pertanyaan berikut dan hasilnya muncul untuk mengkonfirmasi kecurigaan saya:

//**returns 0**
select count(*) from INFORMATION_SCHEMA.TABLE_CONSTRAINTS;

//**returns no rows**
select * from sys.indexes
where object_id = (select object_id from sys.objects where name = 'NAME-OF-TABLE');

//**returns all tables in database**
SELECT name
FROM sys.tables 
WHERE OBJECTPROPERTY(object_id,'IsIndexed') = 0;
ali haider
sumber

Jawaban:

9

Dua pertanyaan ini dapat membantu Anda. Yang pertama akan mencantumkan semua tabel dan indeks pada tabel-tabel itu di basis data Anda. Jika tabel tidak muncul dalam daftar adalah tidak memiliki indeks yang ditentukan. Kueri ini menganggap SQL Server versi 2005 atau lebih baru.

SELECT 
    IndexName = QUOTENAME(I.name), 
    TableName =
        QUOTENAME(SCHEMA_NAME(T.[schema_id])) + 
        N'.' + QUOTENAME(T.name), 
    IsPrimaryKey = I.is_primary_key
FROM sys.indexes AS I
INNER JOIN sys.tables AS T
    ON I.[object_id] = T.[object_id]
WHERE
    I.type_desc <> N'HEAP'
ORDER BY 
    TableName ASC, 
    IndexName ASC;

Kueri kedua akan melaporkan untuk setiap tabel kolom identitas, jika ada pada setiap tabel di database Anda.

SELECT
    TableName =
        QUOTENAME(SCHEMA_NAME(T.[schema_id])) + 
        N'.' + QUOTENAME(T.name), 
    IdentityColumn = COALESCE(QUOTENAME(C.name), N'No identity column')
FROM sys.tables AS T
LEFT OUTER JOIN sys.columns AS C
    ON T.[object_id] = C.[object_id]
    AND C.is_identity = 1
ORDER BY
    TableName ASC;

Untuk membatasi kueri ke tabel tertentu tambahkan WHEREklausa yang mirip dengan:

WHERE T.name = N'NAME-OF-TABLE'
Jeremy
sumber
2

Tidak, ada yang salah.

Pemeriksaan sys.indexesharus mengembalikan baris bahkan jika tabel Anda tidak memiliki indeks. Tumpukan masih memiliki catatan sys.indexesdengan type_desc'HEAP' dan type0.

Saya pikir Anda mungkin perlu memastikan bahwa Anda berada dalam konteks basis data yang tepat karena OBJECT_ID()dan sys.objectskhusus untuk basis data.

Coba ini:

USE MyDatabase

SELECT *
FROM sys.indexes
WHERE object_id = OBJECT_ID('schema.MyTableName')
JNK
sumber
1

Saya tidak yakin jika Anda tertarik pada semua kendala tetapi INFORMATION_SCHEMA.TABLE_CONSTRAINTS tampaknya tidak mengembalikan kendala DEFAULT - TABLE_CONSTRAINTS (Transact-SQL)

PERIKSA, UNIK, KUNCI UTAMA, KUNCI ASING

Kueri ini akan melakukan penghitungan sederhana terhadap sys.objects DMV:

select COUNT(*)
from sys.objects o
where o.type_desc like '%CONSTRAINT%';

Jika Anda tertarik untuk mendaftar tabel, Anda dapat menjalankan sesuatu seperti ini:

select distinct
   o.object_id
 , QUOTENAME(s.name) + '.' + QUOTENAME(o.name) as [object_name]
 , o.type_desc
 , case when dc.parent_object_id is null then 'No' else 'Yes' end as has_default_constraint
 , case when cc.parent_object_id is null then 'No' else 'Yes' end as has_check_constraint
 , case when fk.parent_object_id is null then 'No' else 'Yes' end as has_foreing_key
 , case when kc.parent_object_id is null then 'No' else 'Yes' end as has_primary_key
from sys.objects o
inner join sys.schemas s on s.schema_id = o.schema_id
left outer join sys.default_constraints dc on dc.parent_object_id = o.object_id and dc.schema_id = o.schema_id
left outer join sys.check_constraints cc on cc.parent_object_id = o.object_id and cc.schema_id = o.schema_id
left outer join sys.foreign_keys fk on fk.parent_object_id = o.object_id and fk.schema_id = o.schema_id
left outer join sys.key_constraints kc on kc.parent_object_id = o.object_id and kc.schema_id = o.schema_id
where o.is_ms_shipped = 0
  and o.type = 'U'
order by [object_name];

Yang ini harus memberi Anda info tentang indeks Anda:

select o.name
 , i.*
from sys.objects o
inner join sys.indexes i on i.object_id = o.object_id
where o.is_ms_shipped = 0
  and i.object_id > 100
  and i.index_id > 0
order by o.name
   , i.index_id;
  • Index_Id = 0 - HEAP (tidak akan muncul)
  • Index_Id = 1 - CLUSTERED
  • Index_Id> 1 - NONCLUSTERED
DenisT
sumber
dapatkah Anda menjelaskan mengapa Anda memilikinya object_id > 100?
brianc
@ bluevoodoo1 - tidak wajib tetapi <100 adalah objek sistem tetapi karena menggunakan o.is_ms_shipped = 0, seharusnya tidak menyertakannya. Hanya bermain aman, itu saja
DenisT