Khi nào tôi nên sử dụng mối quan hệ 1-1?


92

Xin lỗi vì câu hỏi noob đó nhưng có nhu cầu thực sự nào về việc sử dụng mối quan hệ 1-1 với các bảng trong cơ sở dữ liệu của bạn không? Bạn có thể triển khai tất cả các trường cần thiết bên trong một bảng. Ngay cả khi dữ liệu trở nên rất lớn, bạn có thể liệt kê các tên cột mà bạn cần trong SELECTcâu lệnh thay vì sử dụng SELECT *. Khi nào bạn thực sự cần sự tách biệt này?

Câu trả lời:


105

1 đến 0..1

  • "1 đến 0..1" giữa lớp siêu và lớp con được sử dụng như một phần của chiến lược "tất cả các lớp trong các bảng riêng biệt" để thực hiện kế thừa .

  • "1 đến 0..1" có thể được biểu diễn trong một bảng duy nhất với phần "0..1" được bao phủ bởi các trường có thể NULL. Tuy nhiên, nếu mối quan hệ chủ yếu là "1 đến 0" chỉ với một vài hàng "1 đến 1", việc tách phần "0..1" thành một bảng riêng biệt có thể tiết kiệm một số lợi ích về bộ nhớ (và hiệu suất bộ nhớ cache). Một số cơ sở dữ liệu lưu trữ NULL tiết kiệm hơn những cơ sở dữ liệu khác, vì vậy "điểm giới hạn" nơi chiến lược này trở nên khả thi có thể thay đổi đáng kể.

1 đến 1

  • Thực tế "1 đến 1" phân vùng dữ liệu theo chiều dọc, có thể có ý nghĩa đối với bộ nhớ đệm. Cơ sở dữ liệu thường triển khai bộ nhớ đệm ở cấp độ trang, không phải ở cấp độ các trường riêng lẻ, vì vậy ngay cả khi bạn chỉ chọn một vài trường từ một hàng, thông thường toàn bộ trang thuộc về hàng đó sẽ được lưu vào bộ nhớ đệm. Nếu một hàng rất rộng và các trường được chọn tương đối hẹp, bạn sẽ kết thúc vào bộ nhớ đệm nhiều thông tin mà bạn không thực sự cần. Trong tình huống như vậy, có thể hữu ích khi phân vùng dữ liệu theo chiều dọc, vì vậy chỉ những phần hoặc hàng hẹp hơn, được sử dụng thường xuyên hơn mới được lưu vào bộ nhớ cache, vì vậy nhiều hàng trong số chúng có thể vừa với bộ nhớ cache, làm cho bộ nhớ đệm hiệu quả "lớn hơn".

  • Một cách sử dụng khác của phân vùng dọc là thay đổi hành vi khóa: cơ sở dữ liệu thường không thể khóa ở cấp độ của các trường riêng lẻ, chỉ có toàn bộ các hàng. Bằng cách tách hàng, bạn cho phép một khóa chỉ diễn ra trên một trong các nửa của hàng.

  • Các trình kích hoạt cũng thường dành riêng cho bảng. Mặc dù về mặt lý thuyết, bạn có thể chỉ có một bảng và trình kích hoạt bỏ qua "nửa sai" của hàng, một số cơ sở dữ liệu có thể áp đặt các giới hạn bổ sung về những gì trình kích hoạt có thể và không thể làm điều này có thể khiến điều này không thực tế. Ví dụ: Oracle không cho phép bạn sửa đổi bảng thay đổi - bằng cách có các bảng riêng biệt, chỉ một trong số chúng có thể thay đổi để bạn vẫn có thể sửa đổi bảng khác từ trình kích hoạt của mình.

  • Các bảng riêng biệt có thể cho phép bảo mật chi tiết hơn.

Những cân nhắc này không liên quan trong hầu hết các trường hợp, vì vậy trong hầu hết các trường hợp, bạn nên xem xét việc hợp nhất các bảng "1 với 1" thành một bảng.


20

Nếu dữ liệu trong một bảng có liên quan đến, nhưng không 'thuộc về' thực thể được mô tả bởi bảng kia, thì đó là một ứng cử viên để giữ nó riêng biệt.

Điều này có thể mang lại lợi thế trong tương lai, nếu dữ liệu riêng biệt cũng cần phải liên quan đến một số đơn vị khác.


19

Nếu bạn đặt hai bảng một-một trong một, có thể bạn sẽ gặp vấn đề về ngữ nghĩa. Ví dụ: nếu mọi thiết bị đều có một bộ điều khiển từ xa, thì việc đặt thiết bị và bộ điều khiển từ xa có nhiều đặc điểm trong một bảng nghe có vẻ không ổn. Bạn thậm chí có thể phải dành thời gian tìm hiểu xem một thuộc tính nào đó thuộc về thiết bị hoặc bộ điều khiển từ xa.

Có thể có trường hợp, khi một nửa số cột của bạn sẽ trống trong một thời gian dài hoặc sẽ không bao giờ được lấp đầy. Ví dụ: một chiếc ô tô có thể có một đoạn giới thiệu với nhiều đặc điểm hoặc có thể không có. Vì vậy, bạn sẽ có rất nhiều thuộc tính không sử dụng.

Nếu bảng của bạn có 20 thuộc tính và chỉ 4 trong số đó được sử dụng đôi khi, bạn nên chia bảng thành 2 bảng vì các vấn đề về hiệu suất.

Trong những trường hợp như vậy, thật không tốt khi có mọi thứ trong một bảng. Ngoài ra, không dễ để đối phó với một bảng có 45 cột!


17

2 xu của tôi.

Tôi làm việc ở một nơi mà tất cả chúng ta đều phát triển trong một ứng dụng lớn và mọi thứ đều là một mô-đun. Ví dụ, chúng ta có một usersbảng, và chúng ta có một mô-đun bổ sung thông tin chi tiết về facebook cho một người dùng, một mô-đun khác bổ sung thông tin chi tiết về twitter cho một người dùng. Chúng tôi có thể quyết định rút phích cắm một trong các mô-đun đó và xóa tất cả chức năng của nó khỏi ứng dụng của chúng tôi. Trong trường hợp này, mọi mô-đun thêm bảng của riêng chúng với các mối quan hệ 1: 1 vào usersbảng chung, như sau:

create table users ( id int primary key, ...);
create table users_fbdata ( id int primary key, ..., constraint users foreighn key ...)
create table users_twdata ( id int primary key, ..., constraint users foreighn key ...)

13

Thời điểm hợp lý nhất để sử dụng điều này sẽ là nếu có hai khái niệm riêng biệt sẽ chỉ liên quan theo cách này. Ví dụ: một chiếc Ô tô chỉ có thể có một Người lái xe hiện tại và Người lái xe chỉ có thể lái một chiếc xe tại một thời điểm - vì vậy mối quan hệ giữa khái niệm Ô tô và Người lái xe sẽ là 1: 1. Tôi chấp nhận rằng đây là ví dụ có sẵn để chứng minh điểm.

Một lý do khác là bạn muốn chuyên môn hóa một khái niệm theo những cách khác nhau. Nếu bạn có bảng Người và muốn thêm khái niệm về các kiểu Người khác nhau, chẳng hạn như Nhân viên, Khách hàng, Cổ đông - mỗi người trong số này sẽ cần các bộ dữ liệu khác nhau. Dữ liệu tương tự giữa chúng sẽ nằm trên bảng Person, thông tin về chuyên gia sẽ nằm trên các bảng cụ thể cho Khách hàng, Cổ đông, Nhân viên.

Một số công cụ cơ sở dữ liệu đấu tranh để thêm một cột mới vào một bảng rất lớn (nhiều hàng) một cách hiệu quả và tôi đã thấy các bảng mở rộng được sử dụng để chứa cột mới, thay vì cột mới được thêm vào bảng ban đầu. Đây là một trong những cách sử dụng bảng bổ sung đáng ngờ hơn.

Bạn cũng có thể quyết định phân chia dữ liệu cho một khái niệm giữa hai bảng khác nhau cho các vấn đề về hiệu suất hoặc khả năng đọc, nhưng đây là một trường hợp khá đặc biệt nếu bạn đang bắt đầu từ đầu - những vấn đề này sẽ tự hiển thị sau.


5

không thường xuyên lắm.

bạn có thể tìm thấy một số lợi ích nếu bạn cần triển khai một số bảo mật - vì vậy một số người dùng có thể thấy một số cột (bảng1) nhưng không thấy một số cột khác (bảng2) ..

tất nhiên một số cơ sở dữ liệu (Oracle) cho phép bạn thực hiện kiểu bảo mật này trong cùng một bảng, nhưng một số cơ sở dữ liệu khác có thể không.


5

Bạn đang đề cập đến việc chuẩn hóa cơ sở dữ liệu. Một ví dụ mà tôi có thể nghĩ đến trong một ứng dụng mà tôi duy trì là Mục. Ứng dụng này cho phép người dùng bán nhiều loại mặt hàng khác nhau (ví dụ: InventoryItems, NonInventoryItems, ServiceItems, v.v.). Mặc dù tôi có thể lưu trữ tất cả các trường theo yêu cầu của mọi mục trong một bảng Mục, nhưng việc duy trì bảng Mục cơ sở chứa các trường chung cho tất cả các mục và sau đó tách các bảng cho từng loại mục sẽ dễ dàng hơn nhiều. vv ..) chứa các trường chỉ dành riêng cho loại mục đó. Sau đó, bảng mục sẽ có một khóa ngoại cho loại mục cụ thể mà nó đại diện. Mối quan hệ giữa các bảng mục cụ thể và bảng mục cơ sở sẽ là 1-1.

Dưới đây, là một bài viết về chuẩn hóa.

http://support.microsoft.com/kb/283878


3

Như với tất cả các câu hỏi về thiết kế, câu trả lời là "nó phụ thuộc."

Có một số cân nhắc:

  • bảng sẽ nhận được kích thước bao nhiêu (cả về trường và hàng)? Có thể bất tiện khi đặt tên người dùng, mật khẩu của bạn với các dữ liệu khác ít được sử dụng hơn cả từ quan điểm bảo trì và lập trình

  • các trường trong bảng kết hợp có các ràng buộc có thể trở nên cồng kềnh khó quản lý theo thời gian. ví dụ: nếu trình kích hoạt cần kích hoạt cho một trường cụ thể, điều đó sẽ xảy ra cho mọi cập nhật cho bảng bất kể trường đó có bị ảnh hưởng hay không.

  • Bạn có chắc chắn rằng mối quan hệ sẽ là 1: 1? Như câu hỏi này đã chỉ ra, mọi thứ có thể trở nên phức tạp nhanh chóng.


3

Một trường hợp sử dụng khác có thể là như sau: bạn có thể nhập dữ liệu từ một số nguồn và cập nhật dữ liệu đó hàng ngày, chẳng hạn như thông tin về sách. Sau đó, bạn tự thêm dữ liệu về một số sách. Sau đó, bạn nên đặt dữ liệu đã nhập vào một bảng khác với dữ liệu của riêng bạn.


2

Tôi thường gặp hai loại mối quan hệ 1: 1 chung trong thực tế:

  1. Mối quan hệ IS-A, còn được gọi là mối quan hệ siêu kiểu / kiểu con. Đây là khi một loại thực thể thực sự là một loại thực thể khác (EntityA IS A EntityB). Ví dụ:

    • Thực thể cá nhân, với các thực thể riêng biệt cho Kế toán, Kỹ sư, Nhân viên bán hàng, trong cùng một công ty.
    • Thực thể mặt hàng, với các thực thể riêng biệt cho Widget, RawMaterial, FinishingGood, v.v.
    • Thực thể ô tô, với các thực thể riêng biệt cho Xe tải, Sedan, v.v.

    Trong tất cả các tình huống này, thực thể siêu kiểu (ví dụ: Người, Vật phẩm hoặc Xe) sẽ có các thuộc tính chung cho tất cả các kiểu con và các thực thể kiểu con sẽ có các thuộc tính duy nhất cho mỗi kiểu con. Khóa chính của kiểu phụ sẽ giống với khóa của siêu kiểu.

  2. Các mối quan hệ "sếp". Đây là khi một người là ông chủ hoặc người quản lý hoặc người giám sát duy nhất của một đơn vị tổ chức (phòng ban, công ty, v.v.). Khi chỉ có một ông chủ được phép cho một đơn vị tổ chức, thì có mối quan hệ 1: 1 giữa thực thể người đại diện cho ông chủ và thực thể đơn vị tổ chức.


1
Tôi thích ví dụ thứ hai. Bạn có thể có thực thể "Phòng ban" và thực thể "Nhân viên". Trong một bộ phận, bạn có nhiều nhân viên và một nhân viên chỉ có thể làm việc trong một bộ phận. Đây là 1: n. Một nhân viên có thể là người giám sát của một bộ phận - chỉ của một bộ phận và bộ phận chỉ có một người giám sát. Vì vậy, bạn kết thúc với hai bảng được kết nối với hai quan hệ - 1: n và 1: 1.
cezar

2

Đầu tiên, tôi nghĩ đó là một câu hỏi về mô hình hóa và xác định những gì bao gồm một thực thể riêng biệt. Giả sử bạn có customersmột và chỉ một đĩa đơn address. Tất nhiên bạn có thể triển khai mọi thứ trong một bảng duy nhất customer, nhưng nếu trong tương lai bạn cho phép anh ta có từ 2 địa chỉ trở lên, thì bạn sẽ cần phải cấu trúc lại điều đó (không thành vấn đề, nhưng hãy đưa ra quyết định có ý thức).

Tôi cũng có thể nghĩ đến một trường hợp thú vị không được đề cập trong các câu trả lời khác mà việc chia nhỏ bảng có thể hữu ích:

Hãy tưởng tượng, một lần nữa, bạn phải customerscó một đĩa đơn addresstừng, nhưng lần này nó không bắt buộc phải có một địa chỉ. Tất nhiên, bạn có thể triển khai điều đó dưới dạng một loạt các NULLcột có thể sử dụng chẳng hạn như ZIP,state,street. Nhưng giả sử rằng bạn một địa chỉ, trạng thái không phải là tùy chọn, nhưng ZIP thì có. Làm thế nào để lập mô hình đó trong một bảng duy nhất? Bạn có thể sử dụng một ràng buộc trên customerbảng, nhưng việc phân chia trong một bảng khác sẽ dễ dàng hơn nhiều và làm cho khóa ngoại là NULLable. Bằng cách đó, mô hình của bạn rõ ràng hơn nhiều khi nói rằng thực thể address là tùy chọn và rằng đó ZIPlà thuộc tính tùy chọn của thực thể đó.


0

Trong thời gian lập trình của tôi, tôi chỉ gặp điều này trong một tình huống. Đó là khi có mối quan hệ 1-nhiều và 1-1 giữa 2 thực thể giống nhau ("Thực thể A" và "Thực thể B").

Khi "Thực thể A" có nhiều "Thực thể B" và "Thực thể B" chỉ có 1 "Thực thể A" và "Thực thể A" chỉ có 1 "Thực thể B" hiện tại và "Thực thể B" chỉ có 1 "Thực thể A".

Ví dụ: một chiếc Ô tô chỉ có thể có một Tài xế hiện tại và Tài xế chỉ có thể lái một ô tô tại một thời điểm - vì vậy mối quan hệ giữa khái niệm Ô tô và Người lái xe sẽ là 1: 1 - Tôi mượn ví dụ này từ câu trả lời của @Steve Fenton

Trường hợp một Tài xế có thể lái nhiều Ô tô, không chỉ cùng một lúc. Vì vậy, các thực thể Xe và Người lái là 1-nhiều hoặc nhiều-nhiều. Nhưng nếu chúng ta cần biết trình điều khiển hiện tại là ai, thì chúng ta cũng cần mối quan hệ 1-1.


0

Một trường hợp sử dụng khác có thể là nếu số cột tối đa trong bảng cơ sở dữ liệu bị vượt quá. Sau đó, bạn có thể tham gia một bàn khác bằng OneToOne

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.