我有以下情况:
包含许多复选框的表单,大约 100 个。
关于如何将它们保存在数据库中,我有 2 个想法:
1. 多列
我创建了一个如下所示的表:
id | box1 | box2 | ... | box100 | updated| created
id: int
box1: bit(1)
SELECT * FROM table WHERE box1 = 1 AND box22 = 1 ...
2. 单数据列
表格很简单:
id | data | updated | created
data: varchar(100)
SELECT * FROM table WHERE data LIKE '_______1___ ... ____1____1'
其中数据看起来像0001100101010......01
表示值是否已选中的每个字符。
考虑到该表将有 200k+ 行,哪个是更具可扩展性的解决方案?
3. JSON 类型的单个数据列
我还没有关于这个的好信息。
或者...
4. 几SETs
5. 几INTs
- 这些要紧凑得多:每个字节大约 8 个复选框。
- 它们的设置/测试有点混乱。
- 由于它们限制为 64 位,因此您需要多个
SET
或INT
. 我建议根据应用程序以某种合乎逻辑的方式对位进行分组。 - 注意
FIND_IN_SET()
。 - 请注意创建值
2^n
(1 << $n)
。 - 请注意
|
和&
运算符。
5 个中哪一个最好? 这取决于您需要运行的查询 - 用于搜索(如有必要?(,插入,更新(如有必要?(和选择。
举个例子:对于INTs
,WHERE (bits & 0x2C08) = 0x2C08
会同时检查 4 个标志是否为"ON"。 该常量可以在应用代码中构造,也可以((1<<13) | (1<<11) | (1<<10) | (1<<3))
用于位 3,10,11,13。 同时,其他标志将被忽略。 如果您需要它们处于"关闭"状态,则测试将WHERE bits ^ 0x2C08 = 0
。 如果这两种测试中的任何一种是您的主要活动,那么 Choice 5 可能是性能和空间的最佳选择,尽管阅读起来有些晦涩难懂。
添加另一个选项时,SET
需要ALTER TABLE
。INT
通常有一些备用位(TINYINT UNSIGNED
有 8 位,...BIGINT UNSIGNED
有 64 个(。 因此,大约在 8 分之一的情况下,您需要一个ALTER
来获得更大的 INT 或添加另一个 INT。 删除选项:建议放弃该 SET 元素或 INT 位。