Saya tahu Anda telah menerima jawaban, tetapi saya sedang menulis ini di tengah jalan, jadi saya memutuskan untuk tetap mempostingnya.
Saya akan mundur sedikit sebelum semoga menjawab pertanyaan Anda. Saat mengembangkan aplikasi dan membangun database, Anda harus SELALU cobalah untuk menyusun segala sesuatunya sedeskriptif dan sekompak mungkin. Akan sangat canggung untuk memiliki variabel/kolom bernama color
dan simpan kata sandi pengguna terenkripsi di sana (aneh, kan?). Ada beberapa konvensi penamaan database standar yang, jika diikuti, membuat hidup jauh lebih mudah khususnya ketika mengembangkan aplikasi yang rumit. Saya akan menyarankan Anda untuk membaca beberapa blog tentang konvensi penamaan. Titik awal yang baik mungkin ini
satu.
Saya sepenuhnya menyadari bahwa dengan perubahan yang disarankan di bawah ini, Anda mungkin perlu menulis ulang sebagian/sepenuhnya kode aplikasi yang telah Anda tulis sejauh ini, tetapi terserah Anda jika Anda benar-benar ingin semuanya bekerja lebih baik.
Mari kita mulai dengan memperbaiki struktur database. Dari tampilannya, Anda sedang menjalankan aplikasi yang mirip dengan newsfeed facebook. Dalam hal ini, menggunakan FOREIGN KEYS
cukup banyak wajib sehingga Anda dapat menjamin beberapa konsistensi data. Contoh skema database di bawah ini menunjukkan bagaimana Anda dapat mencapainya.
-- 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;
Sekarang setelah ini diperbaiki, kita dapat melanjutkan ke langkah berikutnya - memilih umpan berita untuk john123
(yang memiliki user_id=1
). Ini dapat dicapai dengan kueri di bawah ini:
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
Dan di sini
Anda bisa melihatnya beraksi di sqlfiddle. Seperti yang Anda lihat, hanya dengan menyusun database dengan lebih baik, saya telah menghilangkan kebutuhan sub-kueri (yang EXISTS / NOT EXISTS
lakukan sesuai dengan dokumen dan EXPLAIN
). Selanjutnya kode SQL di atas akan jauh lebih mudah untuk dipelihara dan diperluas.
Bagaimanapun, saya harap Anda menemukan ini berguna.