douhua9726 2014-07-08 03:11
浏览 82
已采纳

MYSQL SET数据类型的替代方案

i have a column where i want to store user's subscription (i.e what they have subscribed to on my subscription platform) i tried using SET datatype, but it has a Limit of 64 values, what users can subscribe to could rise beyond 64 and there will be a problem if a user subscribe above 64 items.

i also tried having another table that maps the user_id to the item_id upon subscription, but it could be a drawback when the database begins to grow.

Anyone with a better idea?

  • 写回答

1条回答 默认 最新

  • drwghu6386 2014-07-08 03:23
    关注

    The normative approach for repeating attributes is a second table.

    It's not at all clear why you think the separate table will be a drawback "when the database begins to grow".


    FOLLOWUP

    Q: If i have a second table that has up to 10,000 values of user's subscription and i am looking for a user's only one subscription it will take longer time to query. i am thinking of storing the user's subscription as an object in the users tables like a string object which i ll just query

    A: No, a query of the second table won't take longer, if the second table has suitable indexes.

    The query will actually be faster.

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

    -- example query 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
    

    Compare that to storing the "subscriptions" of a user as a list in a VARCHAR column (the same representation in and out of the database as used for a SET datatype. And writing a query to identify users that have a particular subscription, e.g.

    EXPLAIN
    SELECT u.user_id
      FROM users u
     WHERE FIND_IN_SET(4,u.subscriptions)
    

    You'll find that MySQL will need to inspect every row in the users table to see if the criteria is met.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 使用EMD去噪处理RML2016数据集时候的原理
  • ¥15 神经网络预测均方误差很小 但是图像上看着差别太大
  • ¥15 Oracle中如何从clob类型截取特定字符串后面的字符
  • ¥15 想通过pywinauto自动电机应用程序按钮,但是找不到应用程序按钮信息
  • ¥15 如何在炒股软件中,爬到我想看的日k线
  • ¥15 seatunnel 怎么配置Elasticsearch
  • ¥15 PSCAD安装问题 ERROR: Visual Studio 2013, 2015, 2017 or 2019 is not found in the system.
  • ¥15 (标签-MATLAB|关键词-多址)
  • ¥15 关于#MATLAB#的问题,如何解决?(相关搜索:信噪比,系统容量)
  • ¥500 52810做蓝牙接受端