Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/284.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/68.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 如何为在线交友网站设计用户表?_Php_Mysql_Database Design - Fatal编程技术网

Php 如何为在线交友网站设计用户表?

Php 如何为在线交友网站设计用户表?,php,mysql,database-design,Php,Mysql,Database Design,我正在开发本地在线交友网站的下一个版本,基于PHP和MySQL,我想把事情做好。用户表相当庞大,预计随着新版本的推出,会有更多的增长,因为会有很多钱花在推广上 目前的版本,我猜是7-8岁可能是由不太熟悉PHP和MySQL的人做的,所以我必须从头开始 该社区目前有20多万用户,预计在未来一到两年内将增长到50万到100万。每个用户的个人资料有100多个属性,我必须能够搜索其中至少30-40个 你可以想象,我对创建一个包含200k行和100列的表有点谨慎。我的前任将用户表一分为二。。。一个包含使用和

我正在开发本地在线交友网站的下一个版本,基于PHP和MySQL,我想把事情做好。用户表相当庞大,预计随着新版本的推出,会有更多的增长,因为会有很多钱花在推广上

目前的版本,我猜是7-8岁可能是由不太熟悉PHP和MySQL的人做的,所以我必须从头开始

该社区目前有20多万用户,预计在未来一到两年内将增长到50万到100万。每个用户的个人资料有100多个属性,我必须能够搜索其中至少30-40个

你可以想象,我对创建一个包含200k行和100列的表有点谨慎。我的前任将用户表一分为二。。。一个包含使用和搜索最多的列,另一个包含其余(和大部分)列。但这会导致两个表之间出现严重的同步问题


那么,您认为最好的方法是什么呢?

实体属性值模型可能非常适合您:

添加一个包含三列的表,而不是100列和不断增长的列:


用户标识
属性

如果不查看模式,就无法真正提出任何建议。一般来说,Mysql数据库必须规范化为至少3NF或BNCF。听起来好像它现在还没有标准化,一个表中有100列


此外,您可以使用事务和INNODB引擎轻松地使用外键强制执行引用完整性。

您可以做的是跨两个表拆分用户数据帐户

1)表格:用户

这将包含关于用户的“核心”固定信息,如名字、姓氏、电子邮件、用户名、角色id、注册日期和类似性质的信息

配置文件相关信息可以放在它自己的表中。这将是一个具有key=>val性质的无限可扩展表

2)表格:用户配置文件

字段:用户id、选项、值

用户id:1

选项:配置文件\图像

值:/uploads/12/myimage.png

用户id:1

选项:回答的问题

数值:24

希望这有帮助,
Paul.

一般来说,您不应该为了性能而牺牲数据库的完整性

我要做的第一件事是创建一个包含1百万行虚拟数据的表,并使用压力工具(如
ab
)测试一些典型的查询。结果很可能证明它的性能很好——对于mysql来说,一百万行是小菜一碟。所以,在试图解决一个问题之前,请确保你确实有它

如果发现性能不佳,数据库实际上是瓶颈,考虑一般优化,比如缓存(在所有级别上,从MySQL查询缓存到HTML缓存),得到更好的硬件等等。这在大多数情况下都应该解决。

< P>这本身不是答案,但由于这里很少有人提出属性-价值模型,我只想插话谈谈我的生活经历

我曾经尝试过将这个模型用于一个具有120多个属性的表(每年增长5-10个),并添加了大约100k+行(每6个月一次),索引增长如此之大,以至于需要永远添加或更新单个
用户id

我发现这种设计的问题(并不是说它完全不适合任何情况)是需要在第二个表的
user\u id,attrib
上放置主键。在不知道attrib的潜在长度的情况下,通常会使用更大的长度值,从而增加索引。在我的例子中,attribs可以有3到130个字符。而且,
肯定也会受到相同假设的影响

正如OP所说,这会导致同步问题。想象一下,如果每个属性(或者至少50%的属性)都需要存在

此外,正如OP所建议的,搜索需要在30-40个属性上进行,我无法想象30-40个连接会有多高效,甚至由于长度限制,一个
group\u concat()

我唯一可行的解决方案是返回到一个列数与属性数相同的表。我的索引现在大大缩小了,搜索也更容易了

编辑:而且,没有标准化问题。要么为属性值设置查找表,要么将它们设置为
ENUM()


编辑2:当然,可以说我应该有一个查找表来查找属性可能的值(减少索引大小),但是我应该在该表上建立一个联接。

通常,在担心性能之前,您应该始终正确地获取模式

这样,您就可以做出关于调整模式以解决特定性能问题的明智决策,而不是猜测

你绝对应该走2桌路线。这将大大减少存储量、代码复杂度,以及更改系统以添加新属性的工作量

假设每个属性都可以用一个表示,并且您只寻找对称匹配(即,您试图根据相似的属性而不是意图表达来匹配人)

在一个简单的层次上,查找合适匹配项的查询可能非常昂贵。实际上,您是在N维空间中寻找接近度相同的节点,不幸的是,大多数关系数据库并没有真正针对这种操作进行设置(我相信PostgreSQL支持这种操作)。因此,大多数人可能会从以下内容开始:

SELECT candidate.id, 
 COUNT(*)
FROM users candidate,
  attributes candidate_attrs,
  attributes current_user_attrs
WHERE current_user_attrs.user_id=$current_user 
  AND candidate.user_id<>$current_user
  AND candidate.id=candidate_attrs.user_id
  AND candidate_attrs.attr_type=current_user.attr_type
  AND candidate_attrs.attr_value=current_user.attr_value
GROUP BY candidate.id
ORDER BY COUNT(*) DESC;
选择candidate.id,
计数(*)
从用户候选人,
属性候选属性,
属性当前用户属性
其中,当前用户\u属性.user\u id=$current\u user
和候选者。用户\u id$当前\u用户
和candidate.id=candidate\u attrs.user\u id
和候选者属性属性类型=当前
SELECT candidate.id, 
 COUNT(*)
FROM users candidate,
   attributes candidate_attrs,
   attributes current_user_attrs
WHERE current_user_attrs.user_id=$current_user 
  AND candidate.user_id<>$current_user
  AND candidate.id=candidate_attrs.user_id
  AND candidate_attrs.attr_type=current_user.attr_type
  AND candidate_attrs.attr_value 
     BETWEEN current_user.attr_value+$tolerance
     AND current_user.attr_value-$tolerance
GROUP BY candidate.id
ORDER BY COUNT(*) DESC;
SELECT candidate.id, 
  SUM(1/1+
      ((candidate_attrs.attr_value - current_user.attr_value)
        *(candidate_attrs.attr_value - current_user.attr_value))
  ) as match_score
FROM users candidate,
  attributes candidate_attrs,
  attributes current_user_attrs
WHERE current_user_attrs.user_id=$current_user 
  AND candidate.user_id<>$current_user
  AND candidate.id=candidate_attrs.user_id
  AND candidate_attrs.attr_type=current_user.attr_type
  AND candidate_attrs.attr_value 
   BETWEEN current_user.attr_value+$tolerance
   AND current_user.attr_value-$tolerance
GROUP BY candidate.id
ORDER BY COUNT(*) DESC;
SELECT candidate.id, 
  SUM(1/1+
      ((candidate_attrs.attr_value - current_user.attr_value)
        *(candidate_attrs.attr_value - current_user.attr_value))
  ) as match_score
FROM users candidate,
  attributes candidate_attrs,
  attributes current_user_attrs,
  attribute_subsets s
WHERE current_user_attrs.user_id=$current_user 
  AND candidate.user_id<>$current_user
  AND candidate.id=candidate_attrs.user_id
  AND candidate_attrs.attr_type=current_user.attr_type
  AND candidate_attrs.attr_value
  AND s.subset_name=$required_subset
  AND s.attr_type=current_user.attr_type 
   BETWEEN current_user.attr_value+$tolerance
   AND current_user.attr_value-$tolerance
GROUP BY candidate.id
ORDER BY COUNT(*) DESC;