mysql - 我什么时候应该将数据存储为 JSON?

标签 mysql database laravel database-design relational-database

这是较长的之一,所以系好安全带:P!

考虑一个用户表。它有 ID、密码、电子邮件和一些时间戳。现在,假设我想存储更多信息,例如它们的位置(或任何其他不经常检索的数据)。我可以将其作为 JSON(伪代码)存储在用户表的新列中

{based_in: {address: "here", country:"xx", region: "great"}}

或者我可以创建一个 1:1 相关的 user_location 表来存储该信息。

CREATE TABLE `user_based_in` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `user_id` int(11) DEFAULT NULL,
  `address` int(11) DEFAULT NULL,
  `country` int(11) DEFAULT NULL,
  `region` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`)
)

最后,我还可以创建一个 1:n 相关表 (user_info),它可以以键值格式保存此数据,例如based_in_addressbased_in_country

CREATE TABLE `user_info` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `user_id` int(10) unsigned NOT NULL,
  `key` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
  `value` text COLLATE utf8mb4_unicode_ci NOT NULL,
  PRIMARY KEY (`id`),
  KEY `user_meta_key_index` (`key`)
)

使用第一种方法,我可以添加有关用户的新详细信息,而无需修改后端 - 这很酷。但当我添加更多细节时,我觉得它很快就会变得困惑。

使用第二种方法,我想我可以获得更好的索引,但这意味着每次我想要存储新的用户详细信息时都必须调整后端。

使用第三种方法,我还可以添加新的详细信息(键)而不更改后端 - 但这个解决方案对我来说似乎有点难看,因为它会生成很多行并且无法关联(在上面的示例中,只有前两个选项清楚地表明 based_in_addressbased_in_country 属于同一对象based_in)。

我还可以采用将第一种方法和第三种方法结合起来的混合方法;创建一个 1:n 表,在其值列中存储 JSON。

然后,假设我还想添加他们最喜欢的颜色:P - 它是新表、新列、新行还是新对象?

在性能、可扩展性和灵 active 方面,哪种方法最适合不经常检索的相关数据(这些数据经常会发生变化,因为可能会添加新 key 来存储其他详细信息)?

我们什么时候创建相关表而不是为 1:1 关系创建新列(特别是自从 MySQL 中出现 JSON 以来)?

最终,我什么时候应该将数据存储为 JSON?

附注虽然我知道 NoSQL 可能能够解决这个问题,但我正在寻找 MySQL 的答案!

最佳答案

Ultimately, when should I store my data as JSON?

当您的数据可能不适合整洁的类型化列系统时,可以使用 JSON 类型。当您不确定要在表中放入哪些数据时,您应该谨慎使用。或者,当数据本质上是非结构化的时,这比键/值表更加灵活。

在您的示例中,您非常确定要存储什么:位置信息。这是一个定义明确的问题,您的 user_based_in 表可以很好地处理它。

何时使用 JSON 的一个很好的例子可能是记录对 API 端点的点击。这些参数由每个 API 端点决定,这是表无法知道的。

create table api_log (
    id integer primary key auto_increment,
    endpoint text not null,
    when timestamp not null,
    params json not null
);

A Practical Guide to MySQL JSON Data Type By Example使用类似的场景。

另一个例子可能是当您不确定您可能想要收集哪些额外数据时。

create table stuff (
    ...normal table design...
    other json
);

这允许应用程序推测性地存储额外的数据,使用它,并看看它是否是他们想要添加到结构中的东西。一旦您确定给定的键/值很重要,请将其作为列添加到表中,并将数据从 JSON 传输到新列。这为您提供了传统关系数据库的所有优势。

假设我们认为事情很重要。我们创建一个新的 things 列。将其设置为other->>'$.things'。并从 JSON 列中删除 things 以避免数据冗余。

alter table stuff add column things text;

update stuff
set things = other->>'$.things',
    other = json_remove(other, '$.things')
where other is not null

关于mysql - 我什么时候应该将数据存储为 JSON?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48894059/

相关文章:

mysql - 我应该相信 mysql 会删除我询问的所有行吗?

javascript - 在 MySql javascript 中更新数据

twitter-bootstrap - 使用 Laravel 4 进行简单例份验证

javascript - 确定 dropzone.js 中所有文件何时上传成功

php - PDOStatement::execute(): SQLSTATE[HY093]: 参数编号无效:绑定(bind)变量的数量与标记的数量不匹配

Mysql统计,返回所有字段,如果没有统计则返回0

c# - 如何编写外部连接字符串配置文件并让我的 C# 应用程序识别和读取它?

mysql - 具有产品过滤地理位置的商店定位器

php - Laravel 数据库显示为未配置?

javascript - Node.js API 与 express 和 mysql - WHERE IN 和带有多个逗号分隔值的绑定(bind)参数