【问题标题】:Storing users data efficiently in mysql database在mysql数据库中有效地存储用户数据
【发布时间】:2012-10-24 06:06:35
【问题描述】:

我正在开发一个推荐引擎,因此需要存储大量数据并跟踪用户的一举一动。所以,基本上我的网站是一个产品搜索引擎,将有一组查询作为用户数据。以下是数据集的一些示例

例子

User1 :
1. Apple Ipod tOuch
2. Samsung Galaxy Ace Plus
3. HArry Porter 

User2 :
1. Product1
2. Product2

等等。

一种方法(天真)可能是拥有一个与我的每个用户相关联的 ID,然后拥有一个与该 ID 对应的字符串,该字符串将采用这种形式(字符串以 ~ 分隔):-

Unique ID - Apple IPod TOuch~Samsung Galaxy Ace Plus~HArry Porter 

但考虑到我以后将如何处理这些数据,这种方法效率不高。

任何人都可以想出一个在mysql中相当容易实现的非常有效的模型吗?

如果我的疑问不清楚,请发表评论。

【问题讨论】:

  • 你读过任何关于关系数据库和规范化的文章吗?
  • @RemusRusanu 还没有,但告诉我,我会完成的。谢谢:)
  • 你的方法打破了第一范式。小心这里有龙。如果您确实需要像这样存储数据,那么 NoSQL 替代方案可能更适合您的需求。就像 Remus 提到的,请检查关系数据库的规范化形式以及它们存在的原因。
  • en.wikipedia.org/wiki/Database_normalization 开头。按照维基百科文章末尾列出的链接进行操作。

标签: mysql database database-design relational-database database-management


【解决方案1】:

经典的设计是一张供用户使用的桌子:

Users(user_id,user_name,reg_date....)

产品表:

Products(prod_id,prod_name,prod_cost....)

带有映射用户的表-->产品:

User_products(user_id,prod_id ....)

例子:

用户:

user_id|user_name
1200   | User1 
7856   | User2

产品:

prod_id | prod_name
12900   | Apple Ipod tOuch
45673   | Samsung Galaxy Ace Plus
99876   | HArry Porter 
34590   | Product1
56283   | Product2

用户产品:

user_id | prod_id
1200    |12900
1200    |45673
1200    |99876
7856    |34590
7856    |56283

【讨论】:

  • @PrashantSingh:我不知道你从哪里来,但上面的解决方案绝对是规范的方法。如果用户的数量是无限的,那么简单的方法会遇到同样多的问题,并且在尝试回答“谁拥有产品 1”这个问题时,通过逗号分隔(或 tilda 分隔)的字符串进行搜索是缓慢且无用的。错误地,我将您的评论标记为有用;这既侮辱又无用。
  • @Prashant Singh - 数据库通常处理无穷大的数据集,因此您的情况并不特殊。为了声称哪种方法更好,您必须定义要支持的查询类型。
  • @No'amNewman 我想知道这一点(例如,谁会为该评论点赞,哈哈),您可以通过再次点击点赞取消评论点赞
  • @Esailija:点击向上箭头没有任何作用(至少,对我来说不是)。也许其他人可以对该评论投反对票?
  • @No'amNewman 嗯,那么,该功能一定已被删除,或者我误解了它......不,不能对 cme​​ts 投反对票 :(
【解决方案2】:

避免使用某些标识符分隔的字符串,因为您必须处理提交的数据,否则当您获得大量数据时,您的搜索引擎会非常慢。 我认为 Grisha 是绝对正确的 - 用户或产品搜索(数字 id 搜索),加入映射表将比通过 text/varchar 字段搜索、分隔结果等更快地输出结果。

【讨论】:

    【解决方案3】:

    使用 Grisha 提出的规范方法,查询“谁拥有产品 1”将这样表示

    select user.user_name
    from users inner join user_products on users.user_id = user_products.user_id
    inner join products on products.prod_id = user.products.prod_id
    where products.prod_name = 'Product 1'
    

    这可能看起来很复杂,但实际上非常简单且非常强大。如果 user_products 表中还有购买日期等字段,还可以通过查询的简单扩展,找出这些用户购买产品 1 的时间,或者查找给定时间段内购买该产品的所有用户。

    【讨论】:

    • 它不需要看起来那么复杂。在这种情况下,可以使用SELECT user_name FROM users NATURAL JOIN user_products NATURAL JOIN products WHERE prod_name = 'Product 1'。但是,我通常避免使用NATURAL JOIN,原因与我避免使用SELECT * 的原因相同;可以用JOIN ... USING() 妥协。
    猜你喜欢
    • 2015-07-06
    • 1970-01-01
    • 1970-01-01
    • 2018-01-05
    • 1970-01-01
    • 2011-10-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多