我有一个列,我想存储用户的订阅(即他们在我的订阅平台上订阅了什么)我尝试使用SET数据类型,但它有64个值的限制,用户可以订阅的数量可能超过64个如果用户订阅超过64项,则会出现问题。
我还尝试了另一个表,在订阅时将user_id映射到item_id,但是当数据库开始增长时,这可能是一个缺点。
任何有更好主意的人?
答案 0 :(得分:4)
重复属性的规范方法是第二个表。
为什么你认为当数据库开始增长时,单独的表将成为一个缺点,这一点并不清楚。
<强>后续强>
问:如果我有第二个表,其中包含最多10,000个用户订阅值,并且我正在寻找用户的唯一一个订阅,那么查询将需要更长时间。我正在考虑将用户的订阅存储为用户表中的对象,如字符串对象,我只是查询
答:不,如果第二个表具有合适的索引,则第二个表的查询不会花费更长的时间。
查询实际上会更快。
<强> -- sample table
强>
CREATE TABLE user_subscription
( user_id INT(10) UNSIGNED NOT NULL COMMENT 'PK, FK to user.id'
, subscription_id INT(10) UNSIGNED NOT NULL COMMENT 'PK'
, PRIMARY KEY (user_id,subscription_id)
, UNIQUE KEY user_subscription_UX1 (subscription_id,user_id)
) ENGINE=INNODB ;
<强> -- populate
强>
INSERT INTO user_subscription
SELECT s.d*10000 + u.d*1000 + h.d*100 + t.d*10 + o.d + 1 AS user_id, 1
FROM digit s
JOIN digit u
JOIN digit h
JOIN digit t
JOIN digit o
ORDER BY s.d, u.d, h.d, t.d, o.d ;
INSERT INTO user_subscription
SELECT s.user_id, s.subscription_id + 1
FROM user_subscription s
WHERE s.subscription_id = 1 ;
INSERT INTO user_subscription
SELECT s.user_id, s.subscription_id + 2
FROM user_subscription s
WHERE s.subscription_id <= 2 ;
INSERT INTO user_subscription
SELECT s.user_id, s.subscription_id + 4
FROM user_subscription s
WHERE s.subscription_id <= 4 ;
<强> -- total rows
强>
SELECT COUNT(1) FROM user_subscription
COUNT(1)
----------
800000
<强> -- sample query 1
强>
EXPLAIN
SELECT t.*
FROM user_subscription t
WHERE t.user_id = 878
id select_type table type possible_keys key key_len ref rows Extra
-- ----------- ------ ------ ------------- ------- ------- ----- ------ -----------
1 SIMPLE t ref PRIMARY PRIMARY 4 const 8 Using index
- 示例查询2
EXPLAIN
SELECT t.*
FROM user_subscription t
WHERE t.subscription_id = 4
id select_type table type possible_keys key key_len ref rows Extra
-- ----------- ------ ---- --------------------- --------------------- ------- ----- ------ -------------
1 SIMPLE t ref user_subscription_UX1 user_subscription_UX1 4 const 184412 Using index
将此与将用户的“预订”存储为VARCHAR
列中的列表进行比较(与SET
数据类型中使用的数据库相同或相同的表示形式。并编写查询识别具有特定订阅的用户,例如
EXPLAIN
SELECT u.user_id
FROM users u
WHERE FIND_IN_SET(4,u.subscriptions)
您会发现MySQL需要检查users
表中的每个行,看看是否符合条件。