用于搜索我的年龄组的数据库模式

时间:2011-12-09 05:18:09

标签: sql database database-design database-schema

我一直在努力解决这个问题,现在试图找出如何最有效地做到这一点。

问题如下。我在数据库中有针对特定年龄段销售的商品,例如ages 10 to 20ages 16+,我需要能够进行查询,例如find item that is for 17 year old

这是我最好的两个想法(但我也不喜欢,因为我认为它们效率低下)。

  1. 拥有一个csv列,其值为10-2016+,检索整个列表,并通过它进行解析(不好主意,我知道,虽然这里的想法很新鲜)

  2. 为csv列添加类似10,11,12,13...20的值作为范围,因此我可以使用WHERE ages LIKE "%17%"查找它,对于像16+这样的情况,我必须检索这些使用类似WHERE ages LIKE "%+%"之类的特殊情况并通过这些解析。

  3. 我当然倾向于第二种选择,但在最好的情况下,我正在运行两个查询,一个用于常规项目,另一个用于16+

    有更好的方法吗?如果没有,你认为你可以让我的模型更高效吗?感谢。

4 个答案:

答案 0 :(得分:3)

你可以这样做:

  1. lower_ageupper_age列添加到表中,两个整数都允许NULL。
  2. 如果lower_age为NULL,则没有下限。
  3. 如果upper_age为NULL,则没有上限。
  4. 结合COALESCE和BETWEEN查询。
  5. 澄清(4),你想说这样的话:

    select *
    from your_table
    where $n between coalesce(lower_age, $n) and coalesce(upper_age, $n)
    

    其中$n是您正在寻找的年龄。 BETWEEN使用包含边界,因此coalesce(lower_age, $n)如果$n不为NULL则忽略lower_age并且如果$n >= $n为NULL,则为lower_age(即该边界上的自动为真) ;同样适用于upper_age

    如果某些内容仅适用于11岁的孩子,则[lower_age,upper_age]关闭时间间隔为[11, 11],其中16岁为[16, NULL],6岁及以下为[NULL, 6] ,每个人都是[NULL, NULL],没有人会[23, 11]或其他任何lower_age > upper_age(或者更有可能的是,CHECK约束会使其无效的数据)。< / p>

答案 1 :(得分:1)

您可以通过多种方式实现这一目标。如果您在行中存储用户的年龄(无论如何)。然后您可以查询年龄并使用&gt; 16或者&lt; 30或10-20之间无论如何。另一种选择是将其存储为按位。有一个参考表并存储您的不同范围,如果它们可以有倍数,那么您只需将两个行值相加。

1 = 10
2 = 16+
4 = 10-20
8 = 20-30
16 = 20+
32 = 30+
.
.
.
.

然后在存储人员信息的表中,您可以将列设置为int或bigint,取您的偏好,然后对于他们所属的任何组,您可以通过数字来确定,例如:

Table of Users
ID     Name        BitWise
 1     test          2
 2     something     6 (2+4)
 3     blah          24 (8+16)

然而,我认为这可能有点矫枉过正,你可能最好只将年龄存储为一个正在运行的查询。这很可能是效率最高的。

答案 2 :(得分:1)

你有一系列的选择(没有双关语意)。对于年龄建议,最简单的方法是存储min_age和max_age并进行如下查询:

select * from item where :age between min_age and max_age

您必须决定是否允许这些列的空值(然后您需要使用coalesce()或nvl()或数据库提供的用于处理与空值的比较的任何函数),或者为这些列设置边界值你可以肯定:年龄总会介于两者之间。

或者,您可以使用m:n表

create table item_ages (item_id int not null, age int not null, constraint item_ages_pk primary key (item_id, age)

并用显式值填充:

item_id | age
-------------
      1 | 16
      1 | 17
      1 | 18

等等。这比使用范围更麻烦,但也更灵活,并且由于您的数据库可以索引表并可能将该索引存储在内存中,因此查询应该很快。输入新项目或特定项目的年龄范围发生变化时,您只需触摸此表格。

请注意,CBRRacer的答案具有类似的属性:两者都有一个想法,即您准备一个可以轻松编制索引的数据结构,并回答该索引中的过滤器问题。这是一种在电子商务应用程序中存储营销数据的流行方法。该范围的最终目的是使用专用包来存储用于该目的的反向索引。但是对于一个简单的年龄建议来说当然是矫枉过正的。

答案 3 :(得分:0)

这样的事情:

SELECT *
  FROM tablename
 WHERE 17 BETWEEN start_age AND end_age