数据库结构:具有公共ID的多个表

时间:2014-01-18 18:00:32

标签: php mysql database-design laravel laravel-4

我正在构建一个需要管理各种对象的应用程序(目前只有3个,但可能会随着时间的推移而增加)。所有这些对象都使用相同的格式具有唯一ID,但没有其他共同属性。

所以我为每个对象创建了一个表,但是我想知道如何通过ID进行优化搜索。我想从一开始就构建一个好的进程,因为总行数可能会变得非常高,而且我不希望在几个月内重写代码,因为它会变得太慢。

我想到了NoSQL数据库,但我需要使用MySQL。 PHP代码使用Laravel 4和Eloquent ORM。

假设我想要ID为abcd-123456的项目,我不知道要查询哪个表,所以我想到了这个:

  1. 插入对象时,将ID与表名一起存储在另一个表中(CommonIndex
  2. 按ID查询时,在CommonIndex表中查找表名,存储在$tableName变量中
  3. 在Eloquent中使用$tableName::find('abcd-123456')检索最终数据(使用与我的表完全相同的模型)
  4. 但我担心当我必须以300k +行搜索我的ID时,这个过程会变得迟钝

    有关如何改进此流程或构建新流程的任何想法?

    谢谢!

    编辑:更多信息:

    • 我的表彼此没有链接,每个表都代表一种对象
    • 每个表都有一个ID字段
    • 每个对象都有一个唯一的ID,但格式相同(例如:表1包含对象ab-1 de-3 hi-5表2 cd-2 gh-4 jk-6等...)
    • 来自不同类型的两个对象不能具有相同的ID
    • 我没有分配ID,每个对象已经有一个
    • 大多数搜索都是通过ID完成的,因为它对用户来说更容易
    • 在特定条件下,用户可以搜索与ID不同的字段上的产品,但我对性能没有同样的担忧,因为它非常罕见
    • 要允许在其他字段上搜索,这些特定字段将被编入索引(每个表1或2)
    • 搜索将逐一
    • 如果我在此过程中添加批量搜索,我将逐一处理

2 个答案:

答案 0 :(得分:4)

问题:

抱歉,我无法添加评论,因为我还没有50个代表,但我有一些问题:

ids来自哪里?它来自外部系统吗?或者你给他们ids?

为什么需要按ID搜索?出于内部目的或用户将使用这些ID?

ids真的按字母顺序排列吗?数字会更有效率。

您会同时搜索多个ID还是逐个搜索?


一种可能的解决方案:

你可以做的一件简单的事情(根据你的需要),只使用一个有2列的表:

  • 您的身份证件
  • PHP对象存储为字符串(也称为序列化)

但是有缺点。查看此URL以获取利弊: http://www.mysqlperformanceblog.com/2010/01/21/when-should-you-store-serialized-objects-in-the-database/

(例如,如果你需要搜索除你的id之外的其他属性,它将无法工作。如果你需要经常更新数据库,那么它也不是更有效率)

在PHP中序列化和反序列化对象非常容易:

$a = your_object;
$s = serialize($a);
// save data into database. $s is now your object, but in a string format.

// retreive the value from your database ($s)
$s = get_from_database($id);
$a = unserialize($s);
// do whatever you want now with your object

另一个解决方案是你提到的那个,但我不会存储表名。数字效率更高。


更新:

由于你无法真正存储序列化对象,我认为你建议的是最好的方法。 MySQL的300k是可管理的,只需确保您的id列上有索引。

此外,如果经常搜索特定的列组(例如,用户经常按id,名字和姓氏搜索),您将需要在两列上使用复合索引(需要更多磁盘)空间艰难)。

如果你想确定查询(1获取表格和第2次获取数据)将是有效的,你可以轻松输入带有小PHP脚本(带插入的循环)或数据的300K条目发电机(我找到了这个:http://www.generatedata.com/)。

我会在2个表中输入300k(在“索引”表和一个对象表中)并测试进行2次查询所需的时间,一个在“索引”表上,另一个在对象表上


您可以尝试的另一件事是使用存储过程(您可以根据存储过程中对象的类型选择表)。

答案 1 :(得分:0)

单查询解决方案存在一个基本问题:您不知道每个对象返回的列,因为列取决于类型。

使用CommonIndex表的方法听起来像是一种合理的方法。请确保在每个对象表上编入id列索引。

我确实感到惊讶的是,共享id的通用格式的对象没有共同的任何字段。如果有共同字段,那么这些字段将进入CommonIndex