当我必须处理列中的值列表时,SQL中的好习惯是什么?

时间:2015-11-07 12:44:51

标签: sql sqlite

我是SQL的新手,我想知道如何将多个值的信息编码到一个列中。更准确地说,假设我有这张表:

create table recurrent_events(
    id integer primary key autoincrement,
    weekday integer,
    action text
);

对于某些记录,weekday列必须包含超过1天(例如:星期一,星期五)。

有没有一种很好的方法可以在不使用值列表的情况下执行此操作?

我想过使用标志来存储weekday列中的日期信息:

  • 2^0:星期一
  • 2^1:星期二
  • ...
  • 2^6:星期天

添加与日期对应的2的幂并使用按位AND提取位。

这是一个不错的选择吗?我应该知道是否有替代方案或更好的技术?

2 个答案:

答案 0 :(得分:3)

由于您的表不会无休止地增长并且直观地了解列的内容比保存一些内存/硬盘空间或毫秒来查询结果更重要:

我会在每个工作日创建一个位/布尔列: Mo Tu We ... Su

这比连接表好于" tbl_weekdays"因为你必须确保没有人将同一个工作日分配给同一个事件。

您提到的位编码解决方案与技术POV相比非常优雅,但需要隐含有关位含义的知识。单独的列使这些知识显而易见并简化了SQL查询。

顺便说一句:这个解决方案只能运行,因为不同值的基数低(只有7),否则列数会爆炸。

答案 1 :(得分:1)

您的表格结构表明MySQL(“自动增量”)。

MySQL有一个名为sets的构造,可能就是你要找的东西(文档是here)。集合本身的元素表现得像enum s,并使用位存储。

一般来说,我对使用集合和枚举有很大的保留意见:

  • 它们是特定于数据库的,因此代码对其他系统的可移植性较低。
  • 套装的尺寸有严格的限制。
  • 它们支持难以阅读和维护的神秘编码(WHERE set_col & 1)。
  • 看似相似的集合的定义可能因表格而异。

存储此类信息的“普通”SQL方法是联结表。在您的情况下,每个操作和工作日这将是一行。根据信息的使用方式,一组布尔列,甚至是一周中几天的字符串表示也可能是合适的。