我应该在 MySQL/MariaDB 表中存储 BLOB 长度吗?

问题描述 投票:0回答:3

我正在考虑将 BLOB 存储在我的 MariaDB 中,并在必要时将它们流式传输到基于 Web 的客户端。

我更愿意让客户端知道标头中响应的长度,这意味着在从数据库读取整个内容之前我需要文件长度。我可以想到两种方法来做到这一点:

  1. 将数据库中 blob 的长度存储在单独的列中
  2. SELECT OCTET_LENGTH(blob_field), blob_field FROM table WHERE id=?

我想知道那里的

SELECT OCTET_LENGTH(blob_field)
。数据库必须已经知道blob长度,但引擎是否真的足够聪明,能够理解
OCTET_LENGTH(blob_field)
可以立即知道?或者引擎会读取整个 BLOB 字段并在每次执行
SELECT
时实际计算字节数(当然忽略缓存)?

mysql mariadb blob
3个回答
0
投票

内部 BLOBS(和其他非固定长度类型)总是以长度存储,因此长度函数将访问长度信息(如果没有它,甚至不可能在不知道结尾的情况下逐字节地跳过它们)。

由于 BLOB 的长度也在客户端/服务器协议中传输,因此您可以检索字段信息以获取正确的 Blob 长度(请参阅 --column-info 输出的最大长度)

$ mysql test --column-type-info
MySQL [test]> create table t1 (id int, a blob);
Query OK, 0 rows affected (0.060 sec)

MySQL [test]> insert into t1 values (1, x'0003040003');
Query OK, 1 row affected (0.021 sec)

MySQL [test]> select a from t1 where id=1;
Field   1:  `a`
Catalog:    `def`
Database:   `test`
Table:      `t1`
Org_table:  `t1`
Type:       BLOB
Collation:  binary (63)
Length:     65535
Max_length: 5
Decimals:   0
Flags:      BLOB BINARY

0
投票

LENGTH(col)
给出八位字节长度。

如果这些 blob 很大,请考虑将它们作为文件放在服务器上,并使用其他机制让它们获取它们,例如 HTML 的

<img ...>

我假设您熟悉在发送字符串时如何转义字符串?

我认为 HTTP 有一种机制,可以在给定字节偏移量和长度的情况下请求文件的一部分。 (15年前我必须用它来下载视频,但我不记得细节了。)MySQL可以提供URL和长度,然后客户端完成剩下的工作,而不需要MySQL做任何进一步的工作。

请记住,虽然

LONGBLOB
有 4GB 的限制,但还有其他因素(缓冲区等)使得处理大于 16MB 的任何东西都变得很尴尬。


0
投票

听起来您正在尝试优化而不知道要优化什么。这是一个很好的问题,但我现在无法以某种方式证明。

我将该值与任何其他元数据一起存储,例如 mime 类型图像宽度/高度或视频分辨率和持续时间。每个文件有一些额外的字节,以避免一些幕后计算。

您应该围绕您希望的扩展方式进行优化。您是否存储了大量的小 blob,那么请使用 length 函数,因为列的额外字节可能很重要。如果您的 blob 访问非常频繁,那么请使用额外的列,因为执行时间比少量的额外空间更重要。如果两者都不是,那么这并不重要,因为您永远不会遇到优化墙。

如果有人告诉您,您也需要降低 CPU 周期或存储,请不要看这里。除非满足上述条件之一,否则这不是唾手可得的成果。在表中查找存储过程、计算列或其他重复数据,其中其中一项为真。

如果你想要硬数字,那么创建两个大表。即 1GB+ blob,并在每个 blob 中插入很多。为了公平起见,请将相同的 blob 插入到每个 blob 中,并且不要使它们恰好为 1GB。插入尽可能多的空间,或者如果空间很大,则至少插入 100 个。然后对每个表执行 1000 多个单独的选择查询。提前生成订单,以便它们是相同的。不要同时运行查询。如果这很重要,那么速度应该明显更快。如果没有,那么长度调用可能在幕后进行了优化,您可以使用对您来说更好的那个。

© www.soinside.com 2019 - 2024. All rights reserved.