网站:存储大量用户变量的最佳方法是什么?

时间:2010-02-15 22:14:20

标签: php mysql variables store

我正在使用PHP和MySQL设计一个网站,随着网站的进展,我发现自己在users表中添加了越来越多的列来存储各种变量。

让我想到的是,有更好的方法来存储这些信息吗?只是为了澄清,这些信息是全球性的,可能会受到其他用户的影响,因此cookie无法正常工作,如果他们清除了cookie,我也会丢失这些信息。

我的问题的第二部分是,如果事实证明将数据存储在数据库中是最好的方法,那么拥有大量列或者将相关列组合成分隔的varchar列会更便宜然后在PHP中爆炸它们?

谢谢!

10 个答案:

答案 0 :(得分:3)

根据我的经验,我宁愿让数据库正确而不是开始添加包含多个项目的逗号分隔字段。必须筛选多个以逗号分隔的字段只会损害程序的效率和代码的可读性。

另外,如果你的表增长很多,那么你可能需要考虑将它分成多个由外来依赖项连接的表?

答案 1 :(得分:3)

我创建了一个user_meta表,其中有三列:user_idkeyvalue

答案 2 :(得分:0)

数据库是存储此类数据的绝佳位置,只要它们是变量而不是巨大的图像文件。数据库具有用于存储和检索大量数据的所有优化和规范。您在文件系统级别设置的任何内容都将始终被数据库在速度和功能方面的优势所打败。

  

拥有大量列或者将相关列组合成分隔的varchar列然后在PHP中将它们爆炸会更便宜吗?

性能并不是一个维护问题IMO - 管理数百个列并不好玩。在TEXT字段中存储此类数据(可能是serialize d个对象)是可行的选择 - 只要它100%确定您永远不必对该数据进行任何查询。

但为什么不这样使用规范化的user_variables表:

id  | user_id | variable_name | variable_value

查询要复杂一些,但是全面提供非常干净的表结构。您可以通过这种方式轻松添加任意用户变量。

如果您正在进行大量查询,例如SELECT FROM USERS WHERE variable257 = 'green',您可能必须坚持使用特定列。

答案 3 :(得分:0)

我不会选择将列分组并将其展开。这是不整洁的工作,非常难以管理。相反,也许可以尝试将这些列分布在几个表上并使用InnoDb的事务功能。

如果您仍然不喜欢频繁更新数据库的想法,并且此方法符合您要实现的目标,则可以使用APC's caching function在服务器上“全局”存储(缓存)信息。

答案 4 :(得分:0)

MongoDB(以及它的NoSQL表兄弟)非常适合这样的事情。

答案 5 :(得分:0)

数据库绝对是存储数​​据的最佳位置。 (我假设您正考虑将其存储在平面文件中)否则,使用数据库而不是存储在文件中肯定会获得更好的性能和安全性。

关于将数据存储在多个列中或分隔它们......这是个人选择,但您应该考虑一些事情

  1. 如果你要划分这些项目,你需要考虑你要用它们划分的内容(在你的分界文本中不太可能出现的内容)
  2. 我经常发现尝试可视化你的关卡中的另一个程序员是否能够在没什么帮助的情况下理解你所做的事情是有帮助的。
  3. 是的,正如Pekka所说,如果你想对存储的数据进行查询,你应该坚持使用单独的列
  4. 如果您只想要几个字段的信息,每次不检索和解析所有数据,也可能会略微提升性能
  5. 我建议选择单独的专栏,因为它为您提供了将来更大灵活性的选择。没有什么比必须彻底改变数据结构并将信息迁移到轨道上更糟糕了!

答案 6 :(得分:0)

我建议设置一个memcached服务器(参见http://memcached.org/)。事实证明,许多大型网站是可行的。 PHP有两个扩展,可以将客户端集成到您的运行时(请参阅http://php.net/manual/en/book.memcached.php)。

试一试,你不会后悔的。

修改
当然,这只是经常使用的数据的选项,否则必须一次又一次地从您的数据库加载。请记住,您仍然需要将数据保存到某种持久存储中。

答案 7 :(得分:0)

面向文档的数据库可能就是您所需要的。

如果你想坚持使用关系型数据库,不要采用天真的方法来创建一个包含很多字段的表:

CREATE TABLE SomeEntity (
    ENTITY_ID    CHAR(10)    NOT NULL,
    PROPERTY_1   VARCHAR(50),
    PROPERTY_2   VARCHAR(50),
    PROPERTY_3   VARCHAR(50),
    ...
    PROPERTY_915 VARCHAR(50),
    PRIMARY KEY  (ENTITY_ID)
);

而是定义属性表:

CREATE TABLE Attribute (
    ATTRIBUTE_ID  CHAR(10) NOT NULL,
    DESCRIPTION   VARCHAR(30),
    /* optionally */
    DEFAULT_VALUE /* whatever type you want */,
    /* end_optionally */
    PRIMARY KEY   (ATTRIBUTE_ID)
);

然后定义您的SomeEntity表,其中仅包含基本属性(例如,注册表单中的必填字段):

CREATE TABLE SomeEntity (
    ENTITY_ID   CHAR(10) NOT NULL
    ESSENTIAL_1 VARCHAR(30),
    ESSENTIAL_2 VARCHAR(30),
    ESSENTIAL_3 VARCHAR(30),
    PRIMARY KEY (ENTITY_ID)
);

然后为那些您可能想要或可能不想存储的属性定义一个表。

CREATE TABLE EntityAttribute (
    ATTRIBUTE_ID    CHAR(10) NOT NULL,
    ENTITY_ID       CHAR(10) NOT NULL,
    ATTRIBUTE_VALUE /* the same type as SomeEntity.DEFAULT_VALUE;
                       if you didn't create that field, then any type */,
    PRIMARY KEY     (ATTRIBUTE_ID, ENTITY_ID)
);

显然,在您的情况下,SomeEntity是用户。

答案 8 :(得分:0)

您可以考虑使用triplestorekey-value store来代替MySQL 通过这种方式,您可以获得所有多线程多用户,性能和缓存巫术的好处,并且可以毫不费力地提前计算出您真正想要存储的值。

缺点:找出拥有帽子的爱达荷州所有人的平均工资要贵一些。

答案 9 :(得分:0)

取决于您存储的用户信息类型。如果其会话相关数据,请使用与会话事件处理程序协调的php会话将会话数据存储在数据库中的单个数据字段中。