Mysql
 sql >> Baza danych >  >> RDS >> Mysql

Jak wybrać posty utworzone przeze mnie lub moich znajomych w aktualnościach?

Wiem, że już zaakceptowałeś odpowiedź, ale byłem w połowie pisania tego, więc postanowiłem i tak ją opublikować.

Mam zamiar cofnąć się trochę, zanim mam nadzieję, że odpowiem na twoje pytanie. Tworząc aplikacje i budując bazy danych, powinieneś ZAWSZE spróbuj uporządkować rzeczy tak opisowo i zwięźle, jak to tylko możliwe. Byłoby naprawdę niezręcznie mieć zmienną/kolumnę o nazwie color i przechowuj tam zaszyfrowane hasła użytkowników (dziwne, prawda?). Istnieje kilka standardowych konwencji nazewnictwa baz danych, których przestrzeganie znacznie ułatwia życie, szczególnie podczas tworzenia skomplikowanych aplikacji. Radziłbym przeczytać kilka blogów dotyczących konwencji nazewnictwa. Dobrym punktem wyjścia może być to jeden.

W pełni zdaję sobie sprawę, że po wprowadzeniu poniższych sugerowanych zmian może być konieczne częściowe/całkowite przepisanie kodu aplikacji, który napisałeś do tej pory, ale to od Ciebie zależy, czy naprawdę chcesz, aby wszystko działało lepiej.

Zacznijmy od naprawy struktury bazy danych. Wygląda na to, że tworzysz aplikację podobną do kanału informacyjnego na Facebooku. W takim przypadku użyj FOREIGN KEYS jest prawie obowiązkowe, więc możesz zagwarantować pewną spójność danych. Poniższy przykładowy schemat bazy danych pokazuje, jak możesz to osiągnąć.

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

Teraz, gdy zostało to naprawione, możemy przejść do następnego kroku - wybrania kanału informacyjnego dla john123 (kto ma user_id=1 ). Można to osiągnąć za pomocą poniższego zapytania:

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

I tutaj można było zobaczyć to w akcji w sqlfiddle. Jak widać, dzięki lepszej strukturze bazy danych wyeliminowałem potrzebę podzapytania (co jest tym, co EXISTS / NOT EXISTS wykonaj zgodnie z dokumentacjami i EXPLAIN ). Ponadto powyższy kod SQL byłby znacznie łatwiejszy w utrzymaniu i rozszerzaniu.

W każdym razie mam nadzieję, że uznasz to za przydatne.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Wywołanie funkcji składowej execute() na wartości logicznej in

  2. Wyszukiwanie MySQL na liście przecinków

  3. Jak uzyskać pierwszy rekord w każdej grupie w MySQL?

  4. 2 sposoby na wyświetlenie listy wszystkich funkcji w MySQL

  5. Jak utworzyć id (autoincremented) w Mysql z połączonym z nim ciągiem? używając tylko php