Mysql
 sql >> база данни >  >> RDS >> Mysql

Как да избера публикации, създадени от мен или мои приятели в емисия за новини?

Знам, че вече сте приели отговор, но бях наполовина писал това, така че все пак реших да го публикувам.

Ще се върна малко назад, преди да се надявам да отговоря на въпроса ви. Когато разработвате приложения и създавате бази данни, трябва ВИНАГИ опитайте се да структурирате нещата възможно най-описателно и компактно. Би било наистина неудобно да има променлива/колона с име color и съхранявайте там криптирани потребителски пароли (странно, нали?). Има някои стандартни конвенции за именуване на бази данни, които, когато се следват, правят живота много по-лесен, особено при разработването на сложни приложения. Бих ви посъветвал да прочетете някои блогове относно конвенциите за именуване. Добра отправна точка може да бъде това едно.

Напълно осъзнавам, че с предложените по-долу промени може да се наложи частично/напълно да пренапишете кода на приложението, който сте написали досега, но от вас зависи дали наистина искате нещата да работят по-добре.

Нека започнем с коригиране на структурата на базата данни. На пръв поглед, вие правите приложение, подобно на новинарската лента на Facebook. В този случай се използва FOREIGN KEYS е доста задължителен, така че можете да гарантирате известна последователност на данните. Примерната схема на база данни по-долу показва как можете да постигнете това.

-- 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;

Сега, когато това е поправено, можем да продължим със следващата стъпка - избор на новинарска лента за john123 (който има user_id=1 ). Това може да се постигне със заявката по-долу:

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

И тук можете да го видите в действие в sqlfiddle. Както можете да видите, само чрез по-добро структуриране на базата данни, премахнах нуждата от подзаявка (което е, което EXISTS / NOT EXISTS направете според документите и EXPLAIN ). Освен това горният SQL код би бил много по-лесен за поддръжка и разширяване.

Както и да е, надявам се да намерите това за полезно.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. CONVERT_TZ() Примери – MySQL

  2. Връзката Doctrine2 ManyToMany не записва

  3. PHP Проверете последния ред на MySQL

  4. Проблем с задействането на mysql в грешна схема

  5. Уловима фатална грешка:Обектът от клас DateTime не може да бъде преобразуван в низ