Liệt kê các chỉ mục và các ràng buộc


10

Tôi đang xem xét một cơ sở dữ liệu SQL Server cho một ứng dụng mà tôi đã kế thừa. Tôi đã không nhìn vào SQL Server được khoảng 10 năm, vì vậy xin hãy đồng ý với tôi.

Bảng cơ sở dữ liệu mà tôi đang xem có một bigint NOT NULLcột được gọi id, tuy nhiên, khi tôi kiểm tra các ràng buộc, tôi không thấy bất kỳ và điều tương tự cũng đúng với tất cả các bảng cơ sở dữ liệu.

Tôi có đúng không khi cho rằng không có khóa chính & không có lập chỉ mục (được nhóm hoặc không được bao gồm) trên các bảng này?

Tôi đã chạy các truy vấn sau và kết quả xuất hiện để xác nhận sự nghi ngờ của tôi:

//**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;

Câu trả lời:


9

Hai truy vấn này có thể giúp bạn. Đầu tiên sẽ liệt kê tất cả các bảng và chỉ mục trên các bảng đó trong cơ sở dữ liệu của bạn. Nếu bảng không xuất hiện trong danh sách thì không có bất kỳ chỉ mục nào được xác định trên đó. Các truy vấn này giả định SQL Server phiên bản 2005 hoặc mới hơn.

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;

Truy vấn thứ hai sẽ báo cáo cho mỗi bảng cột nhận dạng, nếu có trên mỗi bảng trong cơ sở dữ liệu của bạn.

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;

Để giới hạn các truy vấn vào một bảng cụ thể, hãy thêm một WHEREmệnh đề tương tự như:

WHERE T.name = N'NAME-OF-TABLE'

2

Không, một cái gì đó không chính xác.

Việc kiểm tra sys.indexessẽ trả về một hàng ngay cả khi bảng của bạn không có chỉ mục. Heap vẫn có một bản ghi sys.indexesvới type_desc'HEAP' và type0.

Tôi nghĩ rằng bạn có thể cần phải chắc chắn rằng bạn đang ở trong bối cảnh cơ sở dữ liệu phù hợp kể từ khi OBJECT_ID()sys.objectslà cơ sở dữ liệu cụ thể.

Thử cái này:

USE MyDatabase

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

1

Tôi không chắc chắn liệu bạn có quan tâm đến tất cả các ràng buộc hay không nhưng Information_SCHema.TABLE_CONSTRAINTS dường như không trả về các ràng buộc DEFAULT - TABLE_CONSTRAINTS (Transact-SQL)

KIỂM TRA, ĐỘC ĐÁO, CHÍNH HÃNG, KHÓA NGOẠI TỆ

Truy vấn này sẽ thực hiện một phép đếm đơn giản đối với DMV sys.objects:

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

Nếu bạn quan tâm đến việc liệt kê các bảng, bạn có thể chạy một cái gì đó như thế này:

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];

Điều này sẽ cung cấp cho bạn thông tin về các chỉ mục của bạn:

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 (sẽ không xuất hiện)
  • Index_Id = 1 - CLUSTERED
  • Index_Id> 1 - KHÔNG GIỚI HẠN

bạn có thể giải thích tại sao bạn có object_id > 100?
brianc

@ bluevoodoo1 - không bắt buộc nhưng <100 là các đối tượng hệ thống nhưng vì sử dụng o.is_ms_shipped = 0, nên không bao gồm chúng. Chỉ cần chơi an toàn, đó là tất cả
DenisT
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.