Zufrieden haben, dass „sicher“ aus „Datenkonsistenz Sicht“ ist, aber in einem beim Abfragen Nachdem eine Abfrage als "1 + N" bezeichnet wird und in der Regel ein Performance-Killer ist, finden Sie leicht eine Dokumentation zum SQL 1 + N-Problem.
Die Lösung ist, den SQL-Server den Auftrag für Sie in einer einzigen Abfrage ausführen zu lassen und dabei Ping Pong zu vermeiden (lesen Sie: TCP-Pakete hin und her, Abfrage analysieren, ...).
Gegeben:
> SELECT * FROM user;
+---------+----------+
| user_id | username |
+---------+----------+
| 1 | root |
| 2 | user2 |
| 3 | user3 |
+---------+----------+
> SELECT * FROM `like`;
+---------+---------+---------+
| like_id | post_id | user_id |
+---------+---------+---------+
| 1 | 1 | 1 |
| 2 | 2 | 1 |
| 3 | 3 | 1 |
| 4 | 4 | 1 |
| 5 | 2 | 2 |
+---------+---------+---------+
> SELECT * FROM `post`;
+---------+--------+
| post_id | text |
+---------+--------+
| 1 | post 1 |
| 2 | post 2 |
| 3 | post 3 |
| 4 | post 4 |
+---------+--------+
Es gibt mehrere Wege, was Sie anfordern möchten, aber ein Weg sein kann:
> SELECT like_id, like.post_id, text,
(SELECT 1 FROM `like`
WHERE post_id = post.post_id AND
user_id = 2 /* logged in user */) AS I_like_it_too
FROM `like`
JOIN post USING (post_id)
WHERE user_id = 1 /* user id of seen profile */;
+---------+---------+--------+---------------+
| like_id | post_id | text | I_like_it_too |
+---------+---------+--------+---------------+
| 1 | 1 | post 1 | NULL |
| 2 | 2 | post 2 | 1 |
| 3 | 3 | post 3 | NULL |
| 4 | 4 | post 4 | NULL |
+---------+---------+--------+---------------+
Die Verwendung der I_like_it_too alias Beitrag anzuzeigen unterschiedlich je nach Bedarf.
Aus Leistungsgründen benötigen Sie einen Index auf like.user_id
, um die ausgewählten Zeilen auf eine kleine Teilmenge zu beschränken, die abhängige Unterabfrage wird nur für diese Teilmenge ausgeführt, also ist das OK.
Eine weitere Möglichkeit sein kann:
> SELECT displayed.like_id, displayed.post_id, text, my_likes.like_id is not null AS i_also_like
FROM `like` AS displayed
JOIN post USING (post_id)
LEFT JOIN `like` AS my_likes ON
displayed.post_id = my_likes.post_id AND
my_likes.user_id = 2 /* logged user */
WHERE displayed.user_id = 1 /* user id of seen profile */;
+---------+---------+--------+-------------+
| like_id | post_id | text | i_also_like |
+---------+---------+--------+-------------+
| 1 | 1 | post 1 | 0 |
| 2 | 2 | post 2 | 1 |
| 3 | 3 | post 3 | 0 |
| 4 | 4 | post 4 | 0 |
+---------+---------+--------+-------------+
Ich sehe nicht, Ihre 'while' Schleife – Justinas
ist sicher wieder in der Schleife abfragen, natürlich, aber die erste SQL hat bereits alles enthalten (SELECT * FROM likes), daher ist Ihre 2. Anfrage wahrscheinlich nutzlos. – Raptor
nein es ist nicht nutzlos, weil die zweite Abfrage überprüft, ob der angemeldete Benutzer auch den gleichen Beitrag mag. Problem ist, dass die Abfrage wird so oft wiederholt, wenn innerhalb einer While-Schleife – max