Sqlserver
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> Sqlserver

Cách tìm số nhận dạng duy nhất tối ưu trong bảng trong SQL Server:sp_special_columns

Trong SQL Server, bạn có thể sử dụng sp_special_columns hệ thống lưu trữ thủ tục để xác định một định danh duy nhất cho bảng. Cụ thể, nó trả về tập hợp các cột tối ưu xác định duy nhất một hàng trong bảng. Nó cũng trả về các cột được cập nhật tự động khi bất kỳ giá trị nào trong hàng được cập nhật bởi một giao dịch.

sp_special_columns tương đương với SQLSpecialColumns trong ODBC.

Nếu không có cột nào có thể xác định duy nhất bảng, tập kết quả sẽ trống.

Cú pháp

Cú pháp như sau:

sp_special_columns [ @table_name = ] 'table_name'     
     [ , [ @table_owner = ] 'table_owner' ]   
     [ , [ @qualifier = ] 'qualifier' ]   
     [ , [ @col_type = ] 'col_type' ]   
     [ , [ @scope = ] 'scope' ]  
     [ , [ @nullable = ] 'nullable' ]   
     [ , [ @ODBCVer = ] 'ODBCVer' ]   
[ ; ]

@table_name đối số là bắt buộc. Những người khác là tùy chọn. Xem tài liệu của Microsoft để biết giải thích chi tiết về từng đối số.

Ví dụ 1 - Cột Khóa Chính

Dưới đây là một ví dụ cơ bản về bảng có cột khóa chính được gọi là PersonId :

EXEC sp_special_columns Person;

Nó cũng có thể chạy như thế này:

EXEC sp_special_columns @table_name = 'Person';

Kết quả:

+---------+---------------+-------------+-------------+-------------+----------+---------+-----------------+
| SCOPE   | COLUMN_NAME   | DATA_TYPE   | TYPE_NAME   | PRECISION   | LENGTH   | SCALE   | PSEUDO_COLUMN   |
|---------+---------------+-------------+-------------+-------------+----------+---------+-----------------|
| 1       | PersonId      | 4           | int         | 10          | 4        | 0       | 1               |
+---------+---------------+-------------+-------------+-------------+----------+---------+-----------------+

Trong trường hợp này, cột khóa chính được trả về. Tôi biết đây là cột khóa chính vì tôi đã tạo bảng bằng mã sau:

CREATE TABLE Person (
  PersonId int primary key, 
  PersonName varchar(500)
  );

Vì vậy, có vẻ như thủ tục được lưu trữ trên thực tế đã trả về cột tối ưu xác định duy nhất bảng này.

Ví dụ 2 - Cột DUY NHẤT

Bảng trong ví dụ này không có khóa chính nhưng có UNIQUE ràng buộc.

Đây là mã được sử dụng để tạo bảng:

CREATE TABLE Event (
  EventId int UNIQUE, 
  EventName varchar(500)
  );

Vì vậy, bây giờ chúng ta hãy thực thi sp_special_columns so với bảng đó:

EXEC sp_special_columns Event;

Kết quả:

+---------+---------------+-------------+-------------+-------------+----------+---------+-----------------+
| SCOPE   | COLUMN_NAME   | DATA_TYPE   | TYPE_NAME   | PRECISION   | LENGTH   | SCALE   | PSEUDO_COLUMN   |
|---------+---------------+-------------+-------------+-------------+----------+---------+-----------------|
| 1       | EventId       | 4           | int         | 10          | 4        | 0       | 1               |
+---------+---------------+-------------+-------------+-------------+----------+---------+-----------------+

Trong trường hợp này, cột có UNIQUE ràng buộc được coi là định danh duy nhất tối ưu.

Tuy nhiên, điều này không nhất thiết có nghĩa là bất kỳ cột bị ràng buộc bởi một UNIQUE ràng buộc sẽ tự động đủ điều kiện làm định danh duy nhất. Kết quả có thể phụ thuộc vào cách xử lý các giá trị null.

Ví dụ 3 - Đối số @nullable

Bạn có thể sử dụng @nullable để xác định xem các cột đặc biệt có thể chấp nhận giá trị null hay không.

Ở đây, tôi chạy lại cùng một mã, ngoại trừ lần này tôi sử dụng @nullable = 'O' .

EXEC sp_special_columns 
  Event, 
  @nullable = 'O';

Kết quả:

(0 rows affected)

Ở đây nó đang sử dụng @nullable = 'U'

EXEC sp_special_columns 
  Event, 
  @nullable = 'U';

Kết quả:

+---------+---------------+-------------+-------------+-------------+----------+---------+-----------------+
| SCOPE   | COLUMN_NAME   | DATA_TYPE   | TYPE_NAME   | PRECISION   | LENGTH   | SCALE   | PSEUDO_COLUMN   |
|---------+---------------+-------------+-------------+-------------+----------+---------+-----------------|
| 1       | EventId       | 4           | int         | 10          | 4        | 0       | 1               |
+---------+---------------+-------------+-------------+-------------+----------+---------+-----------------+

O chỉ định các cột đặc biệt không cho phép giá trị rỗng. U chỉ định các cột có thể null một phần. U là giá trị mặc định.

Đây là những gì sẽ xảy ra nếu tôi tạo cột dưới dạng NOT NULL :

DROP TABLE Event;

CREATE TABLE Event (
  EventId int NOT NULL UNIQUE, 
  EventName varchar(500)
  );

EXEC sp_special_columns 
  Event, 
  @nullable = 'U';

EXEC sp_special_columns 
  Event, 
  @nullable = 'O';

Kết quả:

+---------+---------------+-------------+-------------+-------------+----------+---------+-----------------+
| SCOPE   | COLUMN_NAME   | DATA_TYPE   | TYPE_NAME   | PRECISION   | LENGTH   | SCALE   | PSEUDO_COLUMN   |
|---------+---------------+-------------+-------------+-------------+----------+---------+-----------------|
| 1       | EventId       | 4           | int         | 10          | 4        | 0       | 1               |
+---------+---------------+-------------+-------------+-------------+----------+---------+-----------------+
(1 row affected)
+---------+---------------+-------------+-------------+-------------+----------+---------+-----------------+
| SCOPE   | COLUMN_NAME   | DATA_TYPE   | TYPE_NAME   | PRECISION   | LENGTH   | SCALE   | PSEUDO_COLUMN   |
|---------+---------------+-------------+-------------+-------------+----------+---------+-----------------|
| 1       | EventId       | 4           | int         | 10          | 4        | 0       | 1               |
+---------+---------------+-------------+-------------+-------------+----------+---------+-----------------+
(1 row affected)

Lần này cả OU tạo ra cùng một kết quả.

Nếu bạn có một bảng với nhiều UNIQUE các cột ràng buộc và một số cho phép giá trị rỗng trong khi những cột khác thì không, đối số này có thể có tác động đến việc một số được coi là giá trị nhận dạng duy nhất tối ưu. Xem Ví dụ 7 ở cuối bài viết này để biết ví dụ về ý tôi muốn nói.

Ví dụ 4 - Cột IDENTITY

Bảng trong ví dụ này không có khóa chính hoặc UNIQUE nhưng nó có IDENTITY cột.

Đây là mã được sử dụng để tạo bảng:

CREATE TABLE Product (
  ProductId int IDENTITY, 
  ProductName varchar(500)
  );

Vì vậy, bây giờ chúng ta hãy thực thi sp_special_columns so với bảng đó:

EXEC sp_special_columns Product;

Kết quả:

(0 rows affected)

Vì vậy, có vẻ như IDENTITY không đủ để nhận dạng duy nhất bảng này.

Ví dụ 5 - Khóa chính nhiều cột

Đây là một khóa có khóa chính nhiều cột. Trong trường hợp này, hai cột được sử dụng cho khóa chính.

Đây là mã được sử dụng để tạo bảng:

CREATE TABLE PersonProduct (
  PersonId int, 
  ProductId int,
   CONSTRAINT PK_PersonProduct PRIMARY KEY (PersonId, ProductId)
  ); 

Vì vậy, bây giờ chúng ta hãy thực thi sp_special_columns so với bảng đó:

EXEC sp_special_columns PersonProduct;

Kết quả:

+---------+---------------+-------------+-------------+-------------+----------+---------+-----------------+
| SCOPE   | COLUMN_NAME   | DATA_TYPE   | TYPE_NAME   | PRECISION   | LENGTH   | SCALE   | PSEUDO_COLUMN   |
|---------+---------------+-------------+-------------+-------------+----------+---------+-----------------|
| 1       | PersonId      | 4           | int         | 10          | 4        | 0       | 1               |
| 1       | ProductId     | 4           | int         | 10          | 4        | 0       | 1               |
+---------+---------------+-------------+-------------+-------------+----------+---------+-----------------+

Ví dụ 6 - Khóa chính và Ràng buộc DUY NHẤT

Điều gì sẽ xảy ra nếu có khóa chính một UNIQUE ràng buộc trong cùng một bảng?

Hãy cùng tìm hiểu:

CREATE TABLE PersonEvent (
  PersonEventId int UNIQUE,
  PersonId int, 
  EventId int,
   CONSTRAINT PK_PersonEvent PRIMARY KEY (PersonId, EventId)
  );

Thực thi sp_special_columns so với bảng đó:

EXEC sp_special_columns PersonEvent;

Kết quả:

+---------+---------------+-------------+-------------+-------------+----------+---------+-----------------+
| SCOPE   | COLUMN_NAME   | DATA_TYPE   | TYPE_NAME   | PRECISION   | LENGTH   | SCALE   | PSEUDO_COLUMN   |
|---------+---------------+-------------+-------------+-------------+----------+---------+-----------------|
| 1       | PersonId      | 4           | int         | 10          | 4        | 0       | 1               |
| 1       | EventId       | 4           | int         | 10          | 4        | 0       | 1               |
+---------+---------------+-------------+-------------+-------------+----------+---------+-----------------+

Khóa chính đã thắng.

Điều gì sẽ xảy ra nếu chúng ta chuyển đổi khóa chính và UNIQUE các cột chính xung quanh?

Được rồi, hãy tạo toàn bộ bảng khác chỉ dành cho việc đó:

CREATE TABLE PersonEvent2 (
  PersonEventId int PRIMARY KEY,
  PersonId int UNIQUE, 
  EventId int UNIQUE
  ); 

Thực thi sp_special_columns so với bảng đó:

EXEC sp_special_columns PersonEvent2;

Kết quả:

+---------+---------------+-------------+-------------+-------------+----------+---------+-----------------+
| SCOPE   | COLUMN_NAME   | DATA_TYPE   | TYPE_NAME   | PRECISION   | LENGTH   | SCALE   | PSEUDO_COLUMN   |
|---------+---------------+-------------+-------------+-------------+----------+---------+-----------------|
| 1       | PersonEventId | 4           | int         | 10          | 4        | 0       | 1               |
+---------+---------------+-------------+-------------+-------------+----------+---------+-----------------+

Vì vậy, khóa chính lại chiến thắng.

Ví dụ 7 - Rất nhiều Ràng buộc DUY NHẤT

Điều gì xảy ra nếu mọi cột có UNIQUE ràng buộc?

CREATE TABLE Event2 (
  EventId int UNIQUE, 
  EventName varchar(500) UNIQUE,
  StartDate date UNIQUE,
  EndDate date UNIQUE
  );

Thực thi sp_special_columns so với bảng đó:

EXEC sp_special_columns Event2;

Kết quả:

+---------+---------------+-------------+-------------+-------------+----------+---------+-----------------+
| SCOPE   | COLUMN_NAME   | DATA_TYPE   | TYPE_NAME   | PRECISION   | LENGTH   | SCALE   | PSEUDO_COLUMN   |
|---------+---------------+-------------+-------------+-------------+----------+---------+-----------------|
| 1       | EndDate       | -9          | date        | 10          | 20       | NULL    | 1               |
+---------+---------------+-------------+-------------+-------------+----------+---------+-----------------+

Nhưng hãy xem điều gì sẽ xảy ra nếu chúng ta đặt một trong các cột đó thành NOT NULL , sau đó sử dụng @nullable = 'O' :

DROP TABLE Event2;

CREATE TABLE Event2 (
  EventId int NOT NULL UNIQUE, 
  EventName varchar(500) UNIQUE,
  StartDate date UNIQUE,
  EndDate date UNIQUE
  );

Thực thi sp_special_columns với @nullable = 'O' :

EXEC sp_special_columns 
  Event2,
  @nullable = 'O'; 

Kết quả:

+---------+---------------+-------------+-------------+-------------+----------+---------+-----------------+
| SCOPE   | COLUMN_NAME   | DATA_TYPE   | TYPE_NAME   | PRECISION   | LENGTH   | SCALE   | PSEUDO_COLUMN   |
|---------+---------------+-------------+-------------+-------------+----------+---------+-----------------|
| 1       | EventId       | 4           | int         | 10          | 4        | 0       | 1               |
+---------+---------------+-------------+-------------+-------------+----------+---------+-----------------+

Vì vậy, cột "not nullable" hiện được chọn làm giá trị nhận dạng duy nhất tối ưu.

Bây giờ chúng ta hãy thực thi sp_special_columns với @nullable = 'U' :

EXEC sp_special_columns 
  Event2,
  @nullable = 'U';

Kết quả:

+---------+---------------+-------------+-------------+-------------+----------+---------+-----------------+
| SCOPE   | COLUMN_NAME   | DATA_TYPE   | TYPE_NAME   | PRECISION   | LENGTH   | SCALE   | PSEUDO_COLUMN   |
|---------+---------------+-------------+-------------+-------------+----------+---------+-----------------|
| 1       | EndDate       | -9          | date        | 10          | 20       | NULL    | 1               |
+---------+---------------+-------------+-------------+-------------+----------+---------+-----------------+

Bây giờ nó quay trở lại cột trước đó.


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Ưu điểm về hiệu suất của SQL Server 2016 Enterprise Edition

  2. Trạng thái và phiên hoạt động của SQL Server

  3. Làm cách nào để có được một danh sách các từ riêng biệt được sử dụng trong tất cả các Bản ghi Trường bằng MS SQL?

  4. SQL:Tốt hơn là một Bit hoặc một ký tự (1)

  5. Cách tạo Bảng bằng GUI trong SQL Server - Hướng dẫn SQL Server / T-SQL Phần 37