Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/226.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/63.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 可扩展数据库设计:自动更改表还是序列化()字段BLOB?_Php_Mysql - Fatal编程技术网

Php 可扩展数据库设计:自动更改表还是序列化()字段BLOB?

Php 可扩展数据库设计:自动更改表还是序列化()字段BLOB?,php,mysql,Php,Mysql,我想要一个适应性强的数据库方案。但在我的应用程序中仍然使用一个简单的表数据网关,在这里我只传递一个$data[]数组用于存储。 基本列在初始表方案中确定。然而,在ca 10-20之后会出现一些元字段。我希望有一些灵活性,而不是每次都手动调整数据库,或者更糟糕的是,仅仅因为新字段而更改应用程序逻辑。 因此,现在有两种选择似乎可行,但并不过分。但我不确定可伸缩性或数据库缺陷 1个自动转换表。无论何时保存$data数组,都会将键与当前数据库列进行比较。在将$data插入表之前定义新列。实际上,在测试代

我想要一个适应性强的数据库方案。但在我的应用程序中仍然使用一个简单的表数据网关,在这里我只传递一个$data[]数组用于存储。 基本列在初始表方案中确定。然而,在ca 10-20之后会出现一些元字段。我希望有一些灵活性,而不是每次都手动调整数据库,或者更糟糕的是,仅仅因为新字段而更改应用程序逻辑。 因此,现在有两种选择似乎可行,但并不过分。但我不确定可伸缩性或数据库缺陷

1个自动转换表。无论何时保存$data数组,都会将键与当前数据库列进行比较。在将$data插入表之前定义新列。实际上,在测试代码中似乎很简单:

function save($data, $table="forum") {
   // columns
   if ($new_fields = array_diff(array_keys($data), known_fields($table))) {
      extend_schema($table, $new_fields, $data);
   }
   // save
   $columns = implode("`, `", array_keys($data));
   $qm = str_repeat(",?", count(array_keys($data)) - 1);
   echo ("INSERT INTO `$table` (`$columns`) VALUES (?$qm);");

function known_fields($table) {
   return unserialize(@file_get_contents("db:$table")) ?: array("id");

function extend_schema($table, $new_fields, $data) {
   foreach ($new_fields as $field) {
       echo("ALTER TABLE `$table` ADD COLUMN `$field` VARCHAR;");
因为它主要是元信息字段,所以像VARCHAR一样添加它们就足够了。无论如何,没有人会质疑他们。因此,数据库实际上只是用作存储。 然而,虽然我可能想在移动中添加许多新的$data字段,但它们并不总是被填充的

2将字段序列化为BLOB。任何新的/无关的元字段都可能对数据库不透明。从真实数据库列中简单地排序虚拟字段很简单。元字段可以序列化为blob/text字段,然后:

function ext_save($data, $table="forum") {  
   $db_fields = array("id", "content", "flags", "ext");
   // disjoin
   foreach (array_diff(array_keys($data),$db_fields) as $key) {
      $data["ext"][$key] = $data[$key];
      unset($data[$key]);
   }
   $data["ext"] = serialize($data["ext"]);
在读取查询中取消序列化和解包这个“ext”列是一个很小的开销。优点是数据库中不会有任何稀疏填充的列,因此我想它比自动改变表方法更紧凑、更快。 当然,此方法防止在WHERE或GROUP BY子句中使用新字段之一。但是我认为没有一个可能的元字段是用户代理,作者ip,作者img,投票,点击,最后修改。。无论如何都会/应该在那里使用

所以我现在更喜欢“ext”blob方法,即使是单程票。 这些列通常如何命名?正在查找示例/文档 您会将XML序列化用于非常理论化的数据库查询吗

自适应表方案似乎是一个更干净的接口,即使大多数列可能仍然是空的。这对速度有什么影响?MySQL/innodb可以容纳多少这样的稀疏VARCHAR字段?
但最重要的是:是否有任何标准实现?一个带有自动改变表技巧的伪ORM?存储一个简单的列列表似乎是可行的,但是像pdo::getColumnMeta这样的东西会更健壮。

在您提出的两个想法中,我选择第二个。第一个让我想哭,别这么做

如果您确定不需要基于元字段进行查询,那么序列化是存储它们的一种非常有效的方法

还有第三个更可取的解决方案,您似乎还没有确定,那就是使用透视表。先创建原始表,然后创建第二个表,其模式如下:

metaid   metaname   metavalue
1        colour     red
2        texture    rough
然后,第三个“pivot”表将链接这两个数据

tbl1_id    metaid
1          1
2          2

这样,就没有了稀疏填充的列,您可以保留基于元数据的查询功能。

在您提出的两个想法中,我选择第二个。第一个让我想哭,别这么做

如果您确定不需要基于元字段进行查询,那么序列化是存储它们的一种非常有效的方法

还有第三个更可取的解决方案,您似乎还没有确定,那就是使用透视表。先创建原始表,然后创建第二个表,其模式如下:

metaid   metaname   metavalue
1        colour     red
2        texture    rough
然后,第三个“pivot”表将链接这两个数据

tbl1_id    metaid
1          1
2          2
这样,就没有了稀疏填充的列,并且您可以保留基于元数据进行查询的能力。

我考虑过自连接超表方法。以前使用过类似的方法,并阅读了stackoverflow上的一些相关条目。但对于我目前的应用程序来说,这似乎有些过头了。从数据库的角度来看,这是一个更干净的概念,但接口的开销更大,数据集也太混乱。所以,我可能会使用序列化方法。放弃了第一种方法。因为随着数据库的增长,ALTERTABLE可能不再那么快了。如果预期的数据更少,它可能会起作用。但还是有点奇怪。我考虑过自连接超表方法。以前使用过类似的方法,并阅读了stackoverflow上的一些相关条目。但对于我目前的应用程序来说,这似乎有些过头了。从数据库的角度来看,这是一个更干净的概念,但接口的开销更大,数据集也太混乱。所以,我可能会使用序列化方法。放弃了第一种方法。因为随着数据库的增长,ALTERTABLE可能不再那么快了。如果预期的数据更少,它可能会起作用。但还是有点古怪。