Mysql
 sql >> Datenbank >  >> RDS >> Mysql

Wie wähle ich Beiträge aus, die von mir oder meinen Freunden in einem Newsfeed erstellt wurden?

Ich weiß, dass Sie bereits eine Antwort akzeptiert haben, aber ich war gerade dabei, dies zu schreiben, also habe ich beschlossen, es trotzdem zu posten.

Ich werde ein wenig zurückgehen, bevor ich hoffentlich Ihre Frage beantworte. Beim Entwickeln von Anwendungen und Erstellen von Datenbanken sollten Sie IMMER versuchen Sie, die Dinge so anschaulich und kompakt wie möglich zu strukturieren. Es wäre wirklich umständlich, eine Variable/Spalte mit dem Namen color zu haben und dort verschlüsselte Benutzerkennwörter speichern (seltsam, oder?). Es gibt einige Standardnamenskonventionen für Datenbanken, die, wenn sie befolgt werden, das Leben viel einfacher machen, insbesondere bei der Entwicklung komplizierter Anwendungen. Ich würde Ihnen raten, einige Blogs zu den Namenskonventionen zu lesen. Ein guter Ausgangspunkt könnte dies eins.

Mir ist völlig klar, dass Sie mit den unten vorgeschlagenen Änderungen den Anwendungscode, den Sie bisher geschrieben haben, möglicherweise teilweise/vollständig neu schreiben müssen, aber es liegt an Ihnen, ob Sie wirklich wollen, dass die Dinge besser funktionieren.

Beginnen wir damit, die Datenbankstruktur zu reparieren. So wie es aussieht, machen Sie eine Anwendung, die dem Newsfeed von Facebook ähnelt. Verwenden Sie in diesem Fall FOREIGN KEYS ist ziemlich obligatorisch, sodass Sie eine gewisse Datenkonsistenz garantieren können. Das Beispiel-Datenbankschema unten zeigt, wie Sie das erreichen können.

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

Da dies nun behoben ist, können wir mit dem nächsten Schritt fortfahren – dem Auswählen des Newsfeeds für john123 (der user_id=1 hat ). Dies kann mit der folgenden Abfrage erreicht werden:

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

Und hier Sie könnten es in einem sqlfiddle in Aktion sehen. Wie Sie sehen können, habe ich durch die bessere Strukturierung der Datenbank die Notwendigkeit einer Unterabfrage beseitigt (was EXISTS / NOT EXISTS ist). gemäß der docs und EXPLAIN ). Außerdem wäre der obige SQL-Code viel einfacher zu pflegen und zu erweitern.

Wie auch immer, ich hoffe, Sie finden das nützlich.