-2

我们正在开发基于 LAMP 的软件,以客户数据为中心单元。包含客户数据的表格由各种来源通过导入接口提供。问题是,表不能有固定的模式。可能 X 行有 5 列,Y 行有 20 列。

我们之前的解决方案如下:

CREATE TABLE `customers` (
  `id` int (10) unsigned NOT NULL auto_increment,
  `branch_id` int (10) unsigned NOT NULL,
  `type` tinyint (1) DEFAULT NULL,
  `visible` tinyint (1) DEFAULT NULL,
  `status` tinyint (1) NOT NULL DEFAULT '1',
  `2` varchar (255) NOT NULL,
  `3` varchar (255) NOT NULL,
  `4` varchar (255) NOT NULL,
  `5` varchar (255) NOT NULL,
  `6` varchar (255) NOT NULL,
  `7` varchar (255) NOT NULL,
  `8` varchar (255) NOT NULL,
  `9` varchar (255) NOT NULL,
  `10` varchar (255) NOT NULL,
  `11` varchar (255) NOT NULL,
  `12` varchar (255) NOT NULL,
  `13` varchar (255) NOT NULL,
  `14` varchar (255) NOT NULL,
  `15` varchar (255) NOT NULL,
  `17` varchar (255) NOT NULL,
  PRIMARY KEY (`id`),
  KEY `branch_id` (`branch_id`)
  FULLTEXT KEY `search` (`2`, `3`, `4`, `5`, `6`, `7`, `8`, `9`, `10`, `11`, `12`, `13`, `14`, `15`)
) ENGINE = MyISAM DEFAULT CHARSET = utf8;

这个表开销很大,因为我们不知道表中将存储什么样的数据,所以我们只需要创建 varchar(255) 列。这里没有看到第二个表,我们在其中存储了列的名称。这张表看起来像这样:

id   col   name
====================
1    2     firstname
2    8     zip

如您所见,我们从仅包含基本列的表开始。然后,我们在每次导入或更新完成时检查是否添加了新列或不再需要列。如果是这种情况,我们已经删除了相应的列或添加了新列。此外,我们总是不得不调整附加表。

这个解决方案在速度、简单性和逻辑性方面对我们来说是一种妥协。在我们看来,最明显的解决方案是使用像 MongoDB 这样的面向文档的 DBMS。

不幸的是,我们被迫只使用 MySQL。是否有在 MySQL 中创建无模式表的解决方案?还是有其他更有用的方法?

4

2 回答 2

1

您应该探索EAV模式。如果您使用的是 PHP,那么有一些工具包可以使您的编码更容易:

于 2012-06-15T13:57:57.003 回答
0

我不确定这是否对你有用,我只是在自己学习和探索这样做,所以我欢迎来自社区的任何更正:

鉴于此时我会考虑组合一些“无模式”表那就是

    创建表`客户`(
      `id` int (10) unsigned NOT NULL auto_increment,
      `branch_id` int (10) unsigned NOT NULL,
      `type` tinyint (1) 默认为空,
      `visible` tinyint (1) 默认为 NULL,
      `status` tinyint (1) NOT NULL DEFAULT '1',
       主键(`id`),
      KEY `branch_id` (`branch_id`)
      FULLTEXT KEY `search` (`2`, `3`, `4`, `5`, `6`, `7`, `8`, `9`, ​​`10`, `11`, `12`, `13`、`14`、`15`)
    ) 引擎 = MyISAM 默认字符集 = utf8;

    创建表 cust_info (
    id int(10) unsigned NOT NULL auto_increment,
    custid int(10) 无符号非空,
    名称 varchar(32) 非空,
    值 varchar(255),
    主键(`id`),
    KEY `custid` (`custid`)
    ) 引擎 = MyISAM 默认字符集 = utf8;

现在只需将“额外”信息存储在 cust_info 表中,并将其分配给正确的 custid。如果你希望你的表变得非常大,那么在 mysql 中查找无模式(google it),你可以找到一些关于如何正确实现它的好文章(而不是我上面的 hack)。这些文章讨论了构建索引表,以便您可以在数据库上执行索引维护,而不会使 mysql 进入非常缓慢的响应状态。

于 2012-07-05T22:39:59.383 回答