First thing's first: what I am doing works perfectly fine. I'm just seeing if there is any room for improvements, and if how I'm doing things is standard and/or using good practices.
These are the tables in question:
item
topic
item_topic
item_like_audit
.
This is my use case:
- There are
topic
's that can contain manyitem
's. - Each
item
can have N amount of likes on them. - For each like, a record is stored in the
item_like_audit
table, such that is can be queried at a later time for ranking purposes.
This is what the query is trying to achieve:
- Get all items under a certain topic that received the most likes within the past 7 days.
Can the following query or underlying schema be improved in any way (for performance or memory gains)?
Query:
SELECT DISTINCT item.* FROM item
/* Match items under this specific topic */
JOIN topic
ON topic.slug = ?
AND topic.deleted_at IS NULL
JOIN item_topic
ON item_topic.item_id = item.id
AND item_topic.topic_id = topic.id
AND item_topic.deleted_at IS NULL
/* Match items that have had "like" activity in the past 7 days */
JOIN item_like_audit
ON item_like_audit.item_id = item.id
AND item_like_audit.created_at <= (CURRENT_DATE + INTERVAL 7 DAY)
WHERE item.deleted_at IS NULL
/* Order by highest like count to lowest */
ORDER BY item.like_count DESC
/* Pagination */
LIMIT ? OFFSET ?
Schema:
CREATE TABLE item (
id INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
name VARCHAR(255) NOT NULL,
slug VARCHAR(255) NOT NULL UNIQUE,
tagline VARCHAR(255) NOT NULL,
description VARCHAR(1000) NOT NULL,
price FLOAT NOT NULL,
like_count INT(10) NOT NULL DEFAULT 0,
images VARCHAR(1000) NOT NULL,
created_at TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP NULL DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP,
deleted_at TIMESTAMP NULL DEFAULT NULL,
PRIMARY KEY (id)
);
CREATE TABLE item_like_audit (
id INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
item_id INT(10) UNSIGNED NOT NULL,
user_id INT(10) UNSIGNED NOT NULL,
created_at TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (id),
KEY `item_like_audit_created_at_index` (`created_at`)
);
CREATE TABLE topic (
id INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
name VARCHAR(255) NOT NULL,
slug VARCHAR(255) NOT NULL UNIQUE,
created_at TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP NULL DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP,
deleted_at TIMESTAMP NULL DEFAULT NULL,
PRIMARY KEY (id)
);
CREATE TABLE item_topic (
id INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
item_id INT(10) NOT NULL,
topic_id INT(10) NOT NULL,
created_at TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP NULL DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP,
deleted_at TIMESTAMP NULL DEFAULT NULL,
PRIMARY KEY (id)
);