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

Làm thế nào để chọn các bài đăng do tôi hoặc bạn bè của tôi tạo trong một nguồn cấp tin tức?

Tôi biết bạn đã chấp nhận một câu trả lời, nhưng tôi đã viết được nửa chặng đường nên tôi vẫn quyết định đăng nó.

Tôi sẽ quay lại một chút trước khi hy vọng trả lời câu hỏi của bạn. Khi phát triển ứng dụng và xây dựng cơ sở dữ liệu, bạn nên LUÔN LUÔN cố gắng cấu trúc mọi thứ mang tính mô tả và cô đọng nhất có thể. Sẽ thực sự khó xử nếu có một biến / cột có tên color và lưu trữ mật khẩu người dùng được mã hóa ở đó (lạ đúng không?). Có một số quy ước đặt tên cơ sở dữ liệu tiêu chuẩn, khi được tuân theo, làm cho cuộc sống dễ dàng hơn rất nhiều, đặc biệt là khi phát triển các ứng dụng phức tạp. Tôi khuyên bạn nên đọc một số blog về quy ước đặt tên. Điểm khởi đầu tốt có thể là cái này một.

Tôi hoàn toàn nhận thấy rằng với các thay đổi được đề xuất bên dưới, bạn có thể cần phải viết lại một phần / toàn bộ mã ứng dụng mà bạn đã viết cho đến nay, nhưng tùy thuộc vào bạn nếu bạn thực sự muốn mọi thứ hoạt động tốt hơn.

Hãy bắt đầu bằng cách sửa cấu trúc cơ sở dữ liệu. Nhìn bề ngoài, bạn đang làm một ứng dụng tương tự như newsfeed của facebook. Trong trường hợp này, sử dụng FOREIGN KEYS là bắt buộc khá nhiều, vì vậy bạn có thể đảm bảo một số dữ liệu nhất quán. Lược đồ cơ sở dữ liệu mẫu dưới đây cho thấy cách bạn có thể đạt được điều đó.

-- Application users are stored here.
CREATE TABLE users (
  user_id      INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
  first_name   VARCHAR(255),
  last_name    VARCHAR(255),
  profile_name VARCHAR(255)
) ENGINE=InnoDb;

-- User friendship relations go here
CREATE TABLE friends (
  friend_id   INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
  profile_one INT NOT NULL,
  profile_two INT NOT NULL,
  FOREIGN KEY (profile_one) REFERENCES users (user_id),
  FOREIGN KEY (profile_two) REFERENCES users (user_id)
) ENGINE=InnoDb;

-- User status updates go here
-- This is what will be displayed on the "newsfeed"
CREATE TABLE statuses (
  status_id    INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
  author_id    INT NOT NULL,
  recipient_id INT NOT NULL,
  message      TEXT,
  -- created date ?
  -- last updated date ?
  FOREIGN KEY (author_id)    REFERENCES users (user_id),
  FOREIGN KEY (recipient_id) REFERENCES users (user_id)
) ENGINE=InnoDb;

-- Replies to user statuses go here. (facebook style..)
-- This will be displayed as the response of a user to a certain status
-- regardless of the status's author.
CREATE TABLE replies (
  reply_id  INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
  status_id INT NOT NULL,
  author_id INT NOT NULL,
  message   TEXT,
  FOREIGN KEY (status_id) REFERENCES statuses (status_id),
  FOREIGN KEY (author_id) REFERENCES users    (user_id)
) ENGINE=InnoDb;

Bây giờ điều này đã được khắc phục, chúng tôi có thể tiếp tục với bước tiếp theo - chọn nguồn cấp tin tức cho john123 (người có user_id=1 ). Điều này có thể đạt được với truy vấn dưới đây:

SET @search_id:=1; -- this variable contains the currently logged in user_id so that we don't need to replace the value more than once in the whole query.

SELECT 
    statuses.*,
    author.first_name     AS author_first_name,
    author.last_name      AS author_last_name,
    recipient.first_name  AS recipient_first_name,
    recipient.last_name   AS recipient_last_name
FROM statuses
JOIN users AS author      ON author.user_id    = statuses.author_id
JOIN users AS recipient   ON recipient.user_id = statuses.recipient_id
WHERE (statuses.author_id = @search_id OR statuses.recipient_id = @search_id)
ORDER BY status_id ASC

tại đây bạn có thể thấy nó hoạt động trong một sqlfiddle. Như bạn có thể thấy, chỉ bằng cách cấu trúc cơ sở dữ liệu tốt hơn, tôi đã loại bỏ sự cần thiết của một truy vấn phụ (đó là EXISTS / NOT EXISTS làm theo tài liệu EXPLAIN ). Hơn nữa, mã SQL ở trên sẽ dễ bảo trì và mở rộng hơn rất nhiều.

Dù sao, tôi hy vọng bạn thấy điều này hữu ích.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. MySQL có bỏ qua các giá trị null trên các ràng buộc duy nhất không?

  2. Làm cách nào để tìm các cột riêng biệt trong một truy vấn con lồng nhau trong SQL?

  3. CHỌN * TỪ nhiều bảng. MySQL

  4. MySQL:Nhận kết quả trả về từ CHÈN CHÈN CHÈN

  5. Lỗi nghiêm trọng:Gọi đến một truy vấn hàm thành viên () PHP CLASS