Các khái niệm
Bạn đã hiểu sai một số khái niệm cơ bản, và những khó khăn là kết quả của nó. Trước tiên, chúng tôi phải giải quyết các khái niệm, không phải vấn đề như bạn nhận thức, và do đó, vấn đề của bạn sẽ biến mất.
ID tự động tăng dần, tất nhiên là khóa chính.
Không họ không. Đó là một quan niệm sai lầm phổ biến. Và các vấn đề được đảm bảo sẽ xảy ra sau đó.
Một ID
trường không được là Khóa chính trong tiếng Anh hoặc kỹ thuật hoặc quan hệ.
-
Chắc chắn, trong SQL, bạn có thể khai báo bất kỳ trường trở thành
PRIMARY KEY
, nhưng điều đó không biến nó thành Khóa chính trong tiếng Anh, kỹ thuật hoặc Quan hệ một cách kỳ diệu. Bạn có thể đặt tên cho chihuahua là "Rottweiller", nhưng điều đó không biến nó thành Rottweiller, nó vẫn là chihuahua. Giống như bất kỳ ngôn ngữ nào, SQL chỉ đơn giản thực hiện các lệnh mà bạn đưa ra, nó không hiểuPRIMARY KEY
nghĩa là một cái gì đó Quan hệ, nó chỉ đánh một chỉ mục duy nhất trên cột (hoặc trường). -
Vấn đề là, vì bạn đã khai báo
ID
trở thànhPRIMARY KEY
, bạn nghĩ rằng nó như là một Khóa chính và bạn có thể mong đợi rằng nó có một số phẩm chất của Khóa chính. Ngoại trừ tính duy nhất của ID giá trị , nó không mang lại lợi ích gì. Nó không có phẩm chất nào của Khóa chính, hoặc bất kỳ loại Khóa quan hệ nào cho vấn đề đó. Nó không phải là một Chìa khóa trong tiếng Anh, kỹ thuật hoặc quan hệ. Bằng cách khai báo một khóa không phải là khóa, bạn sẽ chỉ khiến chính mình bối rối và bạn sẽ phát hiện ra rằng có điều gì đó sai nghiêm trọng chỉ khi người dùng phàn nàn về các bản sao trong bảng.
Các bảng quan hệ phải có hàng tính độc đáo
PRIMARY KEY
trên một ID
trường không cung cấp hàng tính độc đáo. Do đó, nó không phải là một bảng Quan hệ chứa các hàng, và nếu không phải là bảng đó, thì nó là một tệp chứa các bản ghi. Nó không có bất kỳ tính toàn vẹn hay sức mạnh nào (ở giai đoạn này, bạn sẽ chỉ biết về sức mạnh kết hợp), hoặc tốc độ mà một bảng trong cơ sở dữ liệu Quan hệ có.
Thực thi mã này (MS SQL 2008) và chứng minh điều đó cho chính bạn. Vui lòng không chỉ đọc và hiểu nó, sau đó tiếp tục đọc phần còn lại của Câu trả lời này, mã này phải được thực thi trước khi đọc tiếp . Nó có giá trị chữa bệnh.
CREATE TABLE dumb_file (
id INT NOT NULL IDENTITY PRIMARY KEY,
name_first CHAR(30) NOT NULL,
name_last CHAR(30) NOT NULL
)
INSERT dumb_file VALUES ( "Mickey", "Mouse" ) -- succeeds
INSERT dumb_file VALUES ( "Mickey", "Mouse" ) -- succeeds, but not intended
INSERT dumb_file VALUES ( "Mickey", "Mouse" ) -- succeeds, but not intended
SELECT * FROM dumb_file
Lưu ý rằng bạn có hàng trùng lặp . Các bảng quan hệ bắt buộc phải có hàng duy nhất . Thêm bằng chứng rằng bạn không có bảng quan hệ hoặc bất kỳ phẩm chất nào của bảng.
Lưu ý rằng trong báo cáo của bạn, điều duy nhất là duy nhất là ID
trường mà không người dùng nào quan tâm, không người dùng nào nhìn thấy, bởi vì nó không phải là dữ liệu, đó là một số điều vô nghĩa bổ sung mà một số "giáo viên" rất ngu ngốc đã bảo bạn đưa vào mỗi tệp. Bạn có bản ghi tính duy nhất nhưng không hàng tính độc đáo.
Về mặt dữ liệu (dữ liệu thực trừ các bổ sung không liên quan), dữ liệu name_last
và name_first
có thể tồn tại mà không có ID
đồng ruộng. Một người có họ và tên mà không có ID được đóng trên trán của họ.
Điều thứ hai mà bạn đang sử dụng khiến bạn bối rối là AUTOINCREMENT.
Nếu bạn đang triển khai hệ thống lưu trữ hồ sơ không có khả năng Quan hệ, chắc chắn, điều này rất hữu ích, bạn không phải viết mã số gia tăng khi chèn bản ghi. Nhưng nếu bạn đang triển khai Cơ sở dữ liệu quan hệ, thì nó không phục vụ mục đích gì cả, bởi vì bạn sẽ không bao giờ sử dụng nó. Có nhiều tính năng trong SQL mà hầu hết mọi người không bao giờ sử dụng.
Hành động sửa chữa
Vì vậy, làm cách nào để nâng cấp, nâng cấp, tệp tin câm chứa đầy các hàng trùng lặp thành bảng Quan hệ, để có được một số phẩm chất và lợi ích của bảng Quan hệ? Có ba bước để thực hiện điều này.
-
Bạn cần hiểu các Phím
- Và vì chúng tôi đã chuyển từ tệp ISAM của những năm 1970 sang Mô hình quan hệ , bạn cần hiểu Các phím quan hệ . Đó là, nếu bạn muốn có được những lợi ích (tính toàn vẹn, sức mạnh, tốc độ) của Cơ sở dữ liệu quan hệ.
Tiến sĩ E F Cood, trong RM của anh ấy , đã tuyên bố rằng:
một khóa được tạo thành từ dữ liệu
và
các hàng trong bảng phải là duy nhất
"Chìa khóa" của bạn không được tạo thành từ dữ liệu. Đó là một số ký sinh trùng bổ sung, không phải dữ liệu, do bạn bị nhiễm căn bệnh của "thầy" của bạn. Hãy nhìn nhận nó như vậy và cho phép bản thân có đầy đủ năng lực tinh thần mà Chúa đã ban cho bạn (lưu ý rằng tôi không yêu cầu bạn suy nghĩ theo những thuật ngữ cô lập hoặc phân mảnh hoặc trừu tượng, tất cả các yếu tố trong cơ sở dữ liệu phải được tích hợp với nhau). Tạo khóa thực từ dữ liệu, và chỉ từ dữ liệu. Trong trường hợp này, chỉ có một Khóa khả thi:
(name_last, name_first).
-
Hãy thử mã này , tuyên bố một ràng buộc duy nhất đối với dữ liệu:
CREATE TABLE dumb_table ( id INT NOT NULL IDENTITY PRIMARY KEY, name_first CHAR(30) NOT NULL, name_last CHAR(30) NOT NULL CONSTRAINT UK UNIQUE ( name_last, name_first ) ) INSERT dumb_table VALUES ( "Mickey", "Mouse" ) -- succeeds INSERT dumb_table VALUES ( "Mickey", "Mouse" ) -- fails, as intended INSERT dumb_table VALUES ( "Minnie", "Mouse" ) -- succeeds SELECT * FROM dumb_table
Bây giờ chúng tôi có tính duy nhất của hàng . Đó là trình tự xảy ra với hầu hết mọi người:họ tạo một tệp cho phép giả mạo; họ không biết tại sao lừa đảo xuất hiện trong trình đơn thả xuống; người dùng la hét; họ chỉnh sửa tệp và thêm chỉ mục để ngăn chặn việc lừa đảo; họ chuyển đến phần sửa lỗi tiếp theo. (Họ có thể làm như vậy đúng hoặc không, đó là một câu chuyện khác.)
-
Mức độ thứ hai. Đối với những người suy nghĩ, những người suy nghĩ vượt ra ngoài sự sửa chữa của nó. Vì bây giờ chúng ta có tính duy nhất hàng, nên tên của Thiên đàng là mục đích của
ID
lĩnh vực, tại sao chúng ta thậm chí có nó ??? Ồ, vì con chihuahua được đặt tên là Rotty và chúng tôi rất ngại chạm vào nó.Tuyên bố rằng nó là
PRIMARY KEY
là sai, nhưng nó vẫn còn, gây ra nhầm lẫn và kỳ vọng sai. Chìa khóa chính hãng duy nhất có, là(name_last, name_fist),
và nó là Khóa thay thế tại thời điểm này.Do đó,
ID
lĩnh vực là hoàn toàn thừa; và chỉ số hỗ trợ nó cũng vậy; vàAUTOINCREMENT
ngu ngốc cũng vậy; và khai báo sai rằng nó là mộtPRIMARY KEY
; và mọi kỳ vọng của bạn về nó đều sai.Do đó, hãy xóa
ID
thừa đồng ruộng. Hãy thử mã này :CREATE TABLE honest_table ( name_first CHAR(30) NOT NULL, name_last CHAR(30) NOT NULL CONSTRAINT PK PRIMARY KEY ( name_last, name_first ) ) INSERT honest_table VALUES ( "Mickey", "Mouse" ) -- succeeds INSERT honest_table VALUES ( "Mickey", "Mouse" ) -- fails, as intended INSERT honest_table VALUES ( "Minnie", "Mouse" ) -- succeeds SELECT * FROM honest_table
Hoạt động tốt, hoạt động như dự định, không có các trường và chỉ số không liên quan.
Hãy ghi nhớ điều này và làm đúng, mọi lúc.
Giáo viên giả dối
Trong những thời điểm cuối cùng này, như đã được khuyên, chúng tôi sẽ có nhiều người trong số họ. Xin lưu ý những "giáo viên" truyền bá ID
các cột, nhờ bằng chứng chi tiết trong bài đăng này, chỉ đơn giản là bạn không hiểu Mô hình quan hệ hoặc Cơ sở dữ liệu quan hệ. Đặc biệt là những người viết sách về nó.
Bằng chứng là chúng bị mắc kẹt trong công nghệ ISAM trước năm 1970. Đó là tất cả những gì họ hiểu, và đó là tất cả những gì họ có thể dạy. Họ sử dụng một vùng chứa cơ sở dữ liệu SQL, để dễ dàng truy cập, khôi phục, sao lưu, v.v., nhưng nội dung là Hệ thống lưu bản ghi thuần túy không có tính toàn vẹn quan hệ, sức mạnh hoặc tốc độ. AFAIC, đó là một gian lận nghiêm trọng.
Ngoài ID
tất nhiên, có một số mục là khái niệm Quan hệ-hoặc-không quan trọng, được kết hợp với nhau, khiến tôi đưa ra một kết luận nghiêm trọng như vậy. Những mục khác nằm ngoài phạm vi của bài đăng này.
Một cặp ngốc cụ thể hiện đang tấn công Dạng bình thường Đầu tiên. Họ thuộc về trại tị nạn.
Trả lời
Bây giờ cho phần còn lại của câu hỏi của bạn.
Có cách nào để tôi có thể tạo bảng quan hệ mà không làm mất các tính năng tăng tự động không?
Đó là một câu tự mâu thuẫn. Tôi tin rằng bạn sẽ hiểu từ lời giải thích của tôi, Bảng quan hệ không cần thiết cho AUTOINCREMENT
"Tính năng, đặc điểm"; nếu tệp có AUTOINCREMENT
, nó không phải là một bảng Quan hệ.
AUTOINCREMENT
chỉ tốt cho một điều:nếu và chỉ khi, bạn muốn tạo bảng tính Excel trong vùng chứa cơ sở dữ liệu SQL, chứa đầy các trường có tên A,
B,
và C,
trên đầu và ghi lại các số ở phía bên trái. Theo thuật ngữ cơ sở dữ liệu, đó là kết quả của một CHỌN, một chế độ xem dữ liệu phẳng, không phải nguồn dữ liệu được sắp xếp (Chuẩn hóa).
Một giải pháp khả thi khác (nhưng không được ưu tiên) có thể là có một khóa chính khác trong bảng đầu tiên, đó là tên người dùng của người dùng, tất nhiên không phải với câu lệnh tăng tự động. Nó có tất yếu không?
Trong công việc kỹ thuật, chúng tôi không quan tâm đến sở thích, bởi vì đó là chủ quan, và nó thay đổi liên tục. Chúng tôi quan tâm đến tính đúng đắn về mặt kỹ thuật, vì điều đó là khách quan và nó không thay đổi.
Vâng, đó là điều không thể tránh khỏi. Bởi vì nó chỉ là vấn đề thời gian; số lượng lỗi; số lượng "không thể thực hiện"; số lượng người dùng la hét, cho đến khi bạn đối mặt với sự thật, vượt qua những khai báo sai của mình và nhận ra rằng:
-
cách duy nhất để đảm bảo rằng người dùng hàng là duy nhất, user_names là duy nhất, là khai báo một
UNIQUE
ràng buộc vào nó -
và loại bỏ
user_id
hoặcid
trong tệp người dùng -
quảng cáo
user_name
tớiPRIMARY KEY
Có, bởi vì toàn bộ vấn đề của bạn với bảng thứ ba, không phải ngẫu nhiên, sau đó được loại bỏ.
Bảng thứ ba đó là Bảng liên kết . Khóa duy nhất bắt buộc (Khóa chính) là sự kết hợp của hai Khóa chính mẹ. Điều đó đảm bảo tính duy nhất của hàng , được xác định bằng Khóa của chúng, không phải bằng IDs.
Tôi đang cảnh báo bạn về điều đó vì chính những "giáo viên" đã dạy bạn lỗi khi triển khai ID
, hướng dẫn lỗi khi triển khai ID
các trường trong Bảng liên kết, trong đó, cũng giống như với một bảng thông thường, nó không cần thiết, không phục vụ mục đích, giới thiệu các bản sao và gây nhầm lẫn. Và điều đó là thừa gấp đôi vì hai chìa khóa cung cấp đã ở đó, nhìn chằm chằm vào mặt chúng ta.
Vì họ không hiểu RM , hoặc Thuật ngữ quan hệ, họ gọi các Bảng liên kết là bảng "liên kết" hoặc "bản đồ". Nếu họ có ID
, chúng thực tế là các tệp.
Bảng tra cứu
ID
các trường đặc biệt là Điều ngu ngốc cần làm cho các bảng Tra cứu hoặc Tham chiếu. Hầu hết chúng đều có các mã dễ nhận biết, không cần liệt kê danh sách các mã trong đó, vì các mã là (nên là) duy nhất.
Hơn nữa, có các mã trong bảng con dưới dạng FK, là một Điều Tốt:mã có ý nghĩa hơn nhiều và nó thường lưu một phép nối không cần thiết:
SELECT ...
FROM child_table -- not the lookup table
WHERE gender_code = "M" -- FK in the child, PK in the lookup
thay vì:
SELECT ...
FROM child_table
WHERE gender_id = 6 -- meaningless to the maintainer
hoặc tệ hơn:
SELECT ...
FROM child_table C -- that you are trying to determine
JOIN lookup_table L
ON C.gender_id = L.gender_id
WHERE L.gender_code = "M" -- meaningful, known
Lưu ý rằng đây là điều không thể tránh khỏi:bạn cần tính duy nhất trên mã tra cứu và tính duy nhất trên mô tả. Đó là phương pháp duy nhất để ngăn chặn các bản sao trong mỗi trong số hai cột:
CREATE TABLE gender (
gender_code CHAR(2) NOT NULL,
name CHAR(30) NOT NULL
CONSTRAINT PK
PRIMARY KEY ( gender_code )
CONSTRAINT AK
UNIQUE ( name )
)
Ví dụ đầy đủ
Từ các chi tiết trong câu hỏi của bạn, tôi nghi ngờ rằng bạn có vấn đề về cú pháp SQL và định nghĩa FK, vì vậy tôi sẽ đưa ra toàn bộ giải pháp bạn cần làm ví dụ (vì bạn chưa đưa ra định nghĩa tệp):
CREATE TABLE user ( -- Typical Identifying Table
user_name CHAR(16) NOT NULL, -- Short PK
name_first CHAR(30) NOT NULL, -- Alt Key.1
name_last CHAR(30) NOT NULL, -- Alt Key.2
birth_date DATE NOT NULL -- Alt Key.3
CONSTRAINT PK -- unique user_name
PRIMARY KEY ( user_name )
CONSTRAINT AK -- unique person identification
PRIMARY KEY ( name_last, name_first, birth_date )
)
CREATE TABLE sport ( -- Typical Lookup Table
sport_code CHAR(4) NOT NULL, -- PK Short code
name CHAR(30) NOT NULL -- AK
CONSTRAINT PK
PRIMARY KEY ( sport_code )
CONSTRAINT AK
PRIMARY KEY ( name )
)
CREATE TABLE user_sport ( -- Typical Associative Table
user_name CHAR(16) NOT NULL, -- PK.1, FK
sport_code CHAR(4) NOT NULL, -- PK.2, FK
start_date DATE NOT NULL
CONSTRAINT PK
PRIMARY KEY ( user_name, sport_code )
CONSTRAINT user_plays_sport_fk
FOREIGN KEY ( user_name )
REFERENCES user ( user_name )
CONSTRAINT sport_occupies_user_fk
FOREIGN KEY ( sport_code )
REFERENCES sport ( sport_code )
)
Ở đó, PRIMARY KEY
khai báo là trung thực, nó là một Khóa chính; không có ID;
không có AUTOINCREMENT;
không có chỉ số phụ; không có hàng trùng lặp; không có kỳ vọng sai lầm; không có vấn đề hậu quả.
Mô hình dữ liệu
Đây là Mô hình Dữ liệu để đi cùng với các định nghĩa.
-
Nếu bạn không quen với Ký hiệu, xin lưu ý rằng mỗi dấu tích nhỏ, khía và dấu, đường liền nét so với nét đứt, các góc vuông và tròn, đều có nghĩa là một cái gì đó rất cụ thể. Tham khảo Ký hiệu IDEF1X .
-
Một bưc tranh đang gia ngan lơi noi; trong trường hợp này, một bức tranh tiêu chuẩn-khiếu nại có giá trị hơn thế; một cái xấu không đáng là tờ giấy mà nó được vẽ ra.
-
Vui lòng kiểm tra các Cụm động từ một cách cẩn thận, chúng bao gồm một tập hợp các Vị ngữ. Phần còn lại của các Dự đoán có thể được xác định trực tiếp từ mô hình. Nếu điều này không rõ ràng, vui lòng hỏi.