【问题标题】:MSSQL2008: Bit arrays and bit-wise operations + database BrainstormMSSQL2008:位数组和位运算+数据库头脑风暴
【发布时间】:2010-11-29 23:49:56
【问题描述】:

我有一个编码问题,我必须存储“注释”和注释适用的日期。 想想:

注 1 嗨,今天客户先生打电话安排这些约会。 2009 年 8 月 30 日、2009 年 8 月 31 日、2009 年 5 月 9 日

注 2 照常营业。 2009 年 8 月 30 日

注 3 餐厅关门了。 2009 年 6 月 9 日

我需要将以下数据存储在数据库中,同时维护索引以进行高效检索,也就是说,我的客户端应用程序需要选择一个日期,并单独或部分检索与该日期相关的所有笔记。

我已经和几位同事和朋友讨论过,并得出了这个设计。 请注意,如果设计优雅,我希望能够将所有信息存储在一个表中,或者更多。

> Date Bitmap | Month | Year | Note
> 101..         9       2009   Blah Blah     // applies to 1st and 3rd
> 0001...       10      2009   Blah2         // applies to the 4th
> 100           9       2009   Blah23

当用户从多日期选择器中选择以下日期时:9 月 1 日 他会得到 Blah Blah 和 Blah23。单个日期时间对象将重复注释,或强制使用外键创建另一个表。

从某种意义上说,我可以在第一列中存储注释适用于一个月中的哪几天。在位图中,事情可能非常高效。任何其他方式(带有 Note-ID 的链接表,或带有 ID 的所有日期的表)都导致注释字段或重复日期的丑陋重复。我也不想考虑让 Text 字段包含带有分隔符的日期集,以及在搜索时解析它的丑陋代码。

如您所知,我在这个项目上花了不少时间。

但是客户端应用程序 RETRIEVE 怎么能说出给定日期集的所有注释呢? MSSQL中是否有任何位操作?所以我可以检索所有的行,比如说,二进制字段的第 5 位和第 7 位中的“1”

我不能使用 BETWEEN,因为我可能有零星的日期,这些日期不在一个范围或任何东西或那种范围内。想想有一个数据类型,它可以表示从 1 到 31 的任何数字。这就是我对位图的看法。

我还要说,我们可以添加一个额外的文本字段,其中实际日期(以实际文本形式)将由例程填充。但对于其余部分,此应用程序将是主界面,用户很少需要查看丑陋的表格。

我是不是过度设计了,还是你能帮帮我?

感谢您的所有回复。

狮子座

【问题讨论】:

  • 大家好,非常感谢您的回复,但我还是有点困惑。这个愚蠢的“注意”可以适用于一天或几天。它们可以是范围或传播,没关系。我正在寻找一种不会重复的方法。如果我有一个 dateTime 列,它将占用两个表。我的客户很疯狂,想把所有东西都放在一张桌子上。这就是为什么我想到了位图,而不是有一个列出日期的文本字段。
  • 客户并不总是正确的。问他们为什么他们想要一张桌子上的所有东西......
  • 如果您的客户联系人熟悉数据建模,那么当您提出业务逻辑不支持他们给您的单表要求的问题时,他们应该会很清楚。
  • 好吧,我也想挑战一下自己。但我想那是一个非常困难的问题。
  • @Leo:希望与 DBA 一起审查数据模型的人 =)

标签: sql-server database-design data-modeling bitwise-operators


【解决方案1】:

是的,你过度设计了。

只需创建一个日期时间列,并将其编入索引。如果要拆分日期时间,请使用 datepart() 等内置函数。

"客户端应用程序如何 RETRIEVE 说,所有的笔记 给定一组日期?”

通过使用WHERE 子句BETWEEN 执行查询开始和结束日期。

将“Note”字段声明为 varchar(n) [n 最多约为 8000)。它只使用笔记占用的空间,而不是最大定义的大小。

【讨论】:

  • 我明白了,我还考虑到笔记系统会变得非常大的事实,有时笔记适用于超过 60 天。你说的是有 60 条记录相同的 255 字节注释。
  • @Leo,不,您不想在每个日期重复相同的注释。您将拥有另一个表,该表存储日期时间戳以及注释表的外键。这样您就可以找到与笔记相关的所有日期,以及与日期相关的所有笔记。对于每个日期的每个注释,此表都会有一个条目。
  • 日期时间戳是否能够指定多组日期,例如 4 日、6 日 .. 等(不是范围)对于如此挑剔,我深表歉意。
  • @Leo:DateTime 列每行仅存储 一个 日期/时间值。请参阅我关于使用有效/到期日期时间列管理涵盖多个日期的笔记的评论。
【解决方案2】:

我会亲自把它分成两张桌子

NOTE
int Id
varchar NoteText

NOTEACTIVITY
int Id
DateTime ActivityDate
int NoteId

这使您的查询变得简单,并为将来提供了很大的灵活性。这将意味着,如果一个注释适用于三个日期,您在 Note 表中有一个条目,在 NoteActivity 表中有三个条目。在某些方面,您可能会在现有设计中遇到这个问题。如果客户希望将注释应用于每个月的第一天,您将复制该行(包括注释)12 次?

或者,如果您已经确定您的笔记位图想法是正确的方法,那么请考虑存储日期数字而不是位图,这样您就可以存储“[1][5][30]”。例如,通过在该列中搜索包含“[5]”的行,这可能会使您的查询更容易运行

【讨论】:

    【解决方案3】:

    如果应用程序需要选择一个日期,并检索与该日期相关的所有注释(完全或部分),那么您需要使用 DateTime 数据类型来存储日期。

    如果备注的业务备注可以跨越数天,则您的 NOTES 表需要 EFFECTIVE_DATEEXPIRY_DATE DateTime 列。日期可能是同一天,也可能是隔天。

    如果您希望注释文本/正文适用于周期日(即 1 月 1 日、13 日、21 日),那么您需要两个表:NOTESNOTE_ACTIVITYNOTE_ACTIVITY 将包含 note_id 以及有效和到期日期。我只是不明白您如何以任何其他方式在数据库中支持与单个文本体相关联的零星日期。

    【讨论】:

    • 我基本上需要一些笔记说“六月等等。”该说明将适用于六月的每一天。如果在客户端应用程序中查找 6 月 4 日,则会出现该注释,以及另一个适用于 4 日和 6 日的注释,或者另一个仅适用于 4 日的注释。
    • Rexem,我很抱歉过于挑剔。我了解您的方法在范围内有效吗?在这里和那里约会怎么样?谢谢 - 我可能会引起愤怒,但这让我很头疼,因为我也过于挑剔了!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-11-28
    • 2019-01-07
    • 1970-01-01
    • 2011-05-11
    • 1970-01-01
    相关资源
    最近更新 更多