2010-05-26 62 views
10

Cách tốt nhất để lưu trữ mối quan hệ người dùng là gì, ví dụ: tình bạn, mà phải là hai chiều (bạn là bạn của tôi, vì vậy tôi là bạn của bạn) trong một rel. cơ sở dữ liệu, ví dụ: MYSql?cách tốt nhất để lưu trữ mối quan hệ người dùng 1: 1 trong cơ sở dữ liệu quan hệ

tôi có thể nghĩ trong hai cách sau:

  1. Mỗi lần một người bạn sử dụng một người dùng khác, tôi muốn thêm hai hàng đến một cơ sở dữ liệu, chèo Một bao gồm các user id của người sử dụng innitiating tiếp theo là UID của người dùng chấp nhận trong cột tiếp theo. Hàng B sẽ là ngược lại.
  2. Bạn chỉ thêm một hàng, UID (người dùng khởi tạo) tiếp theo là UID (chấp nhận người dùng); và sau đó chỉ tìm kiếm qua cả hai cột khi cố gắng tìm hiểu xem người dùng 1 có phải là bạn của người dùng hay không 2.

Chắc chắn có điều gì tốt hơn?

+0

của bạn bè của bạn giống như bạn có thiết kế đúng. Những gì bạn đề cập đến là một sự kết hợp giữa hai bảng để tạo ra một 0..1 hoặc nhiều giữa mỗi bảng và bảng kết hợp. Cuối cùng những gì nó lưới là rất nhiều. Nhưng tôi phải nói đúng với việc xử lý nó theo cách này. –

Trả lời

8

Tôi sẽ có một bảng liên kết cho bạn bè, hoặc bất kỳ thứ gì, với 2 cột là PK, và cả hai đều là FK cho bảng Người dùng.

Cả hai cột sẽ là UID và bạn sẽ có hai hàng cho mỗi mối quan hệ bạn bè (A, B và B, A). Miễn là cả hai cột đều là PK, nó vẫn phải ở định dạng bình thường (mặc dù những người khác được tự do sửa lỗi cho tôi về điều này)

Phức tạp hơn một truy vấn, nhưng không có gì không thể bị trừu tượng hóa bởi thủ tục được lưu trữ hoặc một số logic nghiệp vụ, và nó ở định dạng bình thường, thường là tốt đẹp để có.

+5

Chỉ cần nhớ rằng trong MySQL động cơ mặc định MyISAM không hỗ trợ khóa ngoài, chuyển sang InnoDB. –

+0

Đúng là đủ, nhưng nếu bạn hoàn toàn phải sử dụng MyISAM, bạn có thể loại bỏ những thứ này không phải là FK thực, nhưng nó có thể ảnh hưởng đến tính toàn vẹn và bình thường hóa dữ liệu của bạn, gắn với InnoDB –

+2

Tôi sẽ sử dụng hệ thống này. các truy vấn chọn để tìm kiếm bạn bè, đặc biệt là khi bạn cần tham gia vào bảng này. Tuy nhiên, bạn nên sử dụng các giao dịch và các thủ tục được lưu trữ để đảm bảo cả hai hàng luôn được chèn và xóa cùng nhau (bạn không ** muốn ** vô tình xóa một trong hai hàng). –

3

Sử dụng hàng kép, trong khi nó tạo thêm dữ liệu, sẽ đơn giản hóa rất nhiều truy vấn của bạn và cho phép bạn lập chỉ mục một cách thông minh. Tôi cũng nhớ nhìn thấy thông tin về giải pháp MySQL tùy chỉnh của Twitter trong đó họ sử dụng một trường bổ sung (bạn bè #, về cơ bản) để tự động giới hạn và phân trang. Dường như khá trơn tru: https://blog.twitter.com/2010/introducing-flockdb

-6

Sử dụng kho lưu trữ giá trị khóa, chẳng hạn như Cassandra chẳng hạn.

+0

Yêu cầu cụ thể liên quan đến giải pháp MySQL. – ethanpil

3

Bạn có thể kiểm tra xem số nào trong số hai user_id là thấp nhất và lưu trữ chúng theo một thứ tự cụ thể. Bằng cách này bạn không cần hàng đôi cho một tình bạn và vẫn giữ cho các truy vấn của bạn đơn giản.

user_id_low | user_id_high

một truy vấn đơn giản để kiểm tra xem bạn đã kết bạn với một người nào đó sẽ là:

<?php 
$my_id = 2999; 
$friend_id = 500; 

$lowest = min($my_id, $friend_id); 
$highest= max($my_id, $friend_id); 

query("SELECT * FROM friends WHERE user_id_low=$lowest AND user_id_high=$highest"); 
?> 

Hoặc bạn có thể tìm ra/userid higest thấp nhất sử dụng mysql

<?php 
query("SELECT * FROM friends WHERE user_id_low=LEAST($my_id, $friend_id) AND user_id_high=GREATEST($my_id, $friend_id)"); 
?> 

Và để có được tất cả số điện thoại

<?php 

query("SELECT IF(user_id_low=$my_id,user_id_high,user_id_low) AS friend_id FROM friends WHERE $my_id IN (user_id_low, user_id_high)"); 

?> 
+0

sau khi nhìn vào điều này trong nửa phút và chỉ cảm thấy tôi sẽ đưa ra một lý do chính đáng tại sao điều này không nên được sử dụng. Nhưng không, tôi thì không. Đây không phải là một giải pháp tồi - khá thanh lịch thực sự :) thực sự điều này cũng hỗ trợ một hệ thống, nơi bạn có thể sắp xếp một nhóm ví dụ 100 nhóm bạn bè, chỉ cần đặt tất cả chúng trong một thứ tự asc/desc –

Các vấn đề liên quan