sql >> Database >  >> RDS >> Mysql

Hoe selecteer ik berichten die door mij of mijn vrienden zijn gemaakt in een nieuwsfeed?

Ik weet dat je al een antwoord hebt geaccepteerd, maar ik was halverwege met schrijven, dus besloot ik het toch te posten.

Ik ga een beetje terug voordat ik hopelijk uw vraag beantwoord. Bij het ontwikkelen van applicaties en het bouwen van databases, moet u ALTIJD probeer de zaken zo beschrijvend en compact mogelijk te structureren. Het zou erg onhandig zijn om een ​​variabele/kolom te hebben met de naam color en sla daar versleutelde gebruikerswachtwoorden op (raar, toch?). Er zijn enkele standaard naamgevingsconventies voor databases die, wanneer ze worden gevolgd, het leven een stuk eenvoudiger maken, vooral bij het ontwikkelen van gecompliceerde applicaties. Ik zou je aanraden om wat blogs te lezen over de naamgevingsconventies. Een goed startpunt kan zijn dit een.

Ik realiseer me volledig dat je met de onderstaande voorgestelde wijzigingen misschien de applicatiecode die je tot nu toe hebt geschreven gedeeltelijk/volledig moet herschrijven, maar het is aan jou of je echt wilt dat de dingen beter werken.

Laten we beginnen met het repareren van de databasestructuur. Zo te zien doe je een applicatie die lijkt op de nieuwsfeed van Facebook. In dit geval, met behulp van FOREIGN KEYS is vrijwel verplicht, dus u kunt enige gegevensconsistentie garanderen. Het voorbeelddatabaseschema hieronder laat zien hoe u dat kunt bereiken.

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

Nu dit is opgelost, kunnen we doorgaan met de volgende stap - het selecteren van de nieuwsfeed voor john123 (wie heeft user_id=1 ). Dit kan worden bereikt met de onderstaande vraag:

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

En hier je zou het in actie kunnen zien in een sqlfiddle. Zoals je kunt zien, heb ik door de database beter te structureren, de noodzaak van een subquery geëlimineerd (wat is wat EXISTS / NOT EXISTS is) doen volgens de docs en EXPLAIN ). Bovendien zou de bovenstaande SQL-code een stuk eenvoudiger te onderhouden en uit te breiden zijn.

Hoe dan ook, ik hoop dat je dit nuttig vindt.



  1. Delphi XE5 FireDAC-fout:kan leveranciersbibliotheek [libmysql.dll of libmysqld.dll] niet laden

  2. Ik kijk uit naar PGConf India 2017

  3. MYSQL:lijst met waarden samenvoegen in een tabel

  4. SQL Query-optimalisatie - exec-tijd