代码之家  ›  专栏  ›  技术社区  ›  Stimy

如何管理数据库中的“选择列表”

  •  2
  • Stimy  · 技术社区  · 16 年前

    我有一个带有许多“选择列表”实体的应用程序(用于填充单一选项下拉选择框)。需要从数据库中提取这些实体。如何在数据库中持久化这些实体?我应该为每个选择列表创建一个新表吗?有更好的解决方案吗?

    16 回复  |  直到 16 年前
        1
  •  4
  •   Blorgbeard    16 年前

    你可以这样做:

    PickListContent
    
    IdList  IdPick  Text  
    1       1       Apples
    1       2       Oranges
    1       3       Pears
    2       1       Dogs
    2       2       Cats
    

    以及可选的……

    PickList
    
    Id    Description
    1     Fruit
    2     Pets
    
        2
  •  6
  •   theo    16 年前

    在过去,我创建了一个表,其中包含列表的名称和可接受的值,然后查询它来显示列表。我还包括一个基础值,因此您可以返回列表的显示值,以及一个可能更丑的绑定值(例如,对于规范化数据,返回一个小的int)。

    CREATE TABLE PickList(
        ListName varchar(15),
        Value varchar(15),
        Display varchar(15),
        Primary Key (ListName, Display)
    )
    

    如果要手动定义显示顺序,还可以添加SortOrder字段。

        3
  •  3
  •   Sklivvz    16 年前

    这取决于各种因素:

    • 如果它们是不可变的和非关系的(想想“美国国家的名称”),那么就可以提出一个论点,认为它们根本不应该出现在数据库中:毕竟它们只是简单的格式化一些东西(比如分配的两个字符的代码)。这样做还有一个额外的优点,即您不需要往返于数据库来获取一些永远不会更改的内容,以便填充组合框。

      然后可以在代码中使用枚举,在数据库中使用约束。对于本地化显示,因此需要为每个区域设置不同的格式,然后可以使用XML文件或其他资源来存储文本。

    • 如果他们是关系型的(想想“国家资本”),我也不太相信任何一种方式…但最近我一直在使用XML文件、数据库约束和JavaScript来填充。它工作得很好,在数据库上也很容易。

    • 如果它们不是只读的,但很少更改(即通常不能由最终用户更改,只能由某些编辑器或每日批处理更改),那么我仍然会考虑不将它们存储在数据库中的机会…这取决于具体情况。

    • 在其他情况下,存储在数据库中是一种方法(想想stackoverflow的标签……它们是“查找”,但也可以由最终用户更改——如果需要,可以使用一些缓存。它需要一些小心的锁定,但是它可以很好地工作。

        4
  •  2
  •   knightpfhor    16 年前

    我发现创建单个表是最好的主意。

    我一直在尝试创建一个包含所有选择列表的主表,然后根据类型筛选出来。当它工作的时候,它总是会让人头疼。例如,您可能会发现,您假定为简单选取列表的某些内容并不简单,需要一个额外的字段,现在是将这些数据拆分为一个额外的表,还是扩展主列表?

    从数据库的角度来看,拥有单独的表可以更容易地管理关系完整性,并且在不使用应用程序时更容易解释数据库中的数据。

        5
  •  1
  •   Alex B    16 年前

    我们按照每个选择列表的新表的模式进行操作。例如:

    表果具有列ID、名称和描述。
    值可能包括:
    15000,苹果,红果
    15001,香蕉,黄色,美味

    如果您需要引用另一个表中的水果,您将调用列水果ID并引用水果表中的行的ID值。

        6
  •  1
  •   Adrian Dunston    16 年前

    为列表创建一个表,为列表选项创建一个表。

     # Put in the name of the list
     insert into lists (id, name) values (1, "Country in North America");
    
     # Put in the values of the list
     insert into list_options (id, list_id, value_text) values
       (1, 1, "Canada"),
       (2, 1, "United States of America"),
       (3, 1, "Mexico");
    
        7
  •  1
  •   Randall    16 年前

    首先回答第二个问题:是的,在大多数情况下,我会为每个选择列表创建一个单独的表。尤其是对于完全不同类型的价值观(例如州和城市)。我使用的一般表格格式如下:

    id - identity or UUID field (I actually call the field xxx_id where xxx is the name of the table).  
    name - display name of the item  
    display_order - small int of order to display.  Default this value to something greater than 1  
    

    如果您愿意,可以添加一个单独的“value”字段,但我通常只使用id字段作为选择框值。

    我通常使用一个select,它首先按显示顺序排序,然后按名称排序,这样您可以按字母顺序排序,同时还可以添加自己的异常。例如,假设您有一个按字母顺序排列的国家列表,但您可以说是美国第一,加拿大第二 "SELECT id, name FROM theTable ORDER BY display_order, name" and set the display_order value for the US as 1, Canada as 2 and all other countries as 9.

    你可以变得更喜欢,比如有一个“active”标志,这样你就可以激活或停用选项,或者设置一个“x”类型的字段,这样你就可以对选项、描述列进行分组,以便在工具提示中使用,等等。但是基本表在大多数情况下都能很好地工作。

        8
  •  1
  •   Ed Lucas    16 年前

    两张桌子。如果您试图将所有内容塞进一个表中,那么您将破坏规范化(如果您关心的话)。以下是示例:

    LIST
    ---------------
    LIST_ID (PK)
    NAME
    DESCR
    
    
    LIST_OPTION
    ----------------------------
    LIST_OPTION_ID (PK)
    LIST_ID (FK)
    OPTION_NAME
    OPTION_VALUE
    MANUAL_SORT
    

    列表表只是描述一个选择列表。列表选项表描述了给定列表中的每个选项。因此,您的查询总是从知道要填充哪个选择列表(通过名称或ID)开始,您要将哪个选择列表加入到列表选项表中,以提取所有选项。手动排序列是为了防止您执行除按名称或值以外的特定顺序。(顺便说一句,每当我试图发布用下划线连接的单词“list”和“option”时,预览窗口就会有点古怪。这就是为什么我在那里放了一个地方。)

    查询的内容如下:

    select
      b.option_name,
      b.option_value
    from
      list a,
      list_option b
    where
      a.name="States"
    and
      a.list_id = b.list_id
    order by
      b.manual_sort asc
    

    如果您认为自己会在WHERE子句中使用list.name,那么您还需要在它上创建一个索引。pk和fk列通常会自动建立索引。

    请不要为每个选择列表创建一个新表,除非您放入“相关”数据,这些数据将被应用程序用于其他地方。您将完全避开数据库提供的关系功能。最好静态地将选择列表定义为基类或属性文件中的某个常量(您可以选择如何建模名称-值对)。

        9
  •  0
  •   neouser99    16 年前

    根据您的需要,您可以只拥有一个选项表,其中有一个列表标识符和一个列表值作为主键。

    select optionDesc from Options where 'MyList' = optionList
    

    然后,您可以用order列等扩展它。如果您有一个id字段,那么您就可以引用您的答案了…如果经常更改,您可以将答案值复制到答案表中。

        10
  •  0
  •   Chris J    16 年前

    如果您不介意为实际值使用字符串,您只需为每个列表提供一个不同的值列表,并用以下内容填充一个表:

    ItmithID:int

    ListIdID: int

    文本:varchar(50)

    似乎最简单,除非每个列表项需要多个内容

        11
  •  0
  •   mattruma    16 年前

    我们实际上创建了实体来处理 简单的 挑选名单。我们创建了一个查找表,其中包含所有可用的选择列表,以及一个包含查找的所有名称/值记录的查找值表。

    当我们需要的时候对我们很有用 简单的 .

        12
  •  0
  •   Stephen Wrighton    16 年前

    我以两种不同的方式完成了这项工作: 1)每个列表的唯一表 2)列表的主表,其中包含提供特定视图的视图

    我倾向于使用初始选项,因为它使更新列表更容易(至少在我看来)。

        13
  •  0
  •   Per Hornshøj-Schierbeck    16 年前

    试着把问题转过来。为什么需要从数据库中提取它?数据不是模型的一部分,但您真的希望将其持久化到数据库中吗?您可以使用像linq2sql或nhibernate这样的或映射器(假设您在.NET环境中),或者根据您可以手动将其存储在一个表中的数据来确定每个表中的数据-在某些情况下,将所有数据都放在同一个表中是很有意义的,但只有当您觉得这很有意义时才考虑这一点。通常,将不同的数据放在不同的表中会使(稍后)更容易理解正在发生的事情。

        14
  •  0
  •   Alex Weinstein    16 年前

    这里有几种方法。

    1)为每个选择列表创建一个表。每个表都有id和name列;用户选择的值将基于所选项目的id进行存储。

    2)创建包含所有选择列表的单个表。列:id;列表id(或列表类型);名称。当需要填充列表时,请执行查询“选择列表ID为..的所有项”。这种方法的优点:非常容易添加选择列表;缺点:编写按样式分组的查询有点困难(例如,给出选择值X的记录数)。

    我个人更喜欢选项1,它对我来说似乎更“干净”。

        15
  •  0
  •   JasonS    16 年前

    您可以为每个表使用单独的表(我的首选),也可以使用具有类型列的公共选择列表表从应用程序中筛选。一般来说,我不确定其中一个是否比另一个有很大的好处。

    如果您有25个以上的表,那么从组织上来说,使用单表解决方案可能更容易,这样您就不会有几个选择列表表凌乱您的数据库。

    如果您的列表很长,那么为每个表使用单独的表可能会有更好的性能,但是如果索引设置得当,这可能是可以忽略的。

    我喜欢使用单独的表,这样,如果选择列表中的某些内容发生更改(例如,它需要附加属性),您可以只更改该选择列表表,而对架构的其余部分几乎没有影响。在单表解决方案中,要么取消选择列表数据的规格化,要么将选择列表拉到单独的表中,等等。在单独的表解决方案中,约束也更容易实施。

        16
  •  0
  •   JosephStyons    16 年前

    这对我们很有帮助:

    SQL> desc aux_values;
     Name                                      Type
     ----------------------------------------- ------------
     VARIABLE_ID                               VARCHAR2(20)
     VALUE_SEQ                                 NUMBER
     DESCRIPTION                               VARCHAR2(80)
     INTEGER_VALUE                             NUMBER
     CHAR_VALUE                                VARCHAR2(40)
     FLOAT_VALUE                               FLOAT(126)
     ACTIVE_FLAG                               VARCHAR2(1)
    

    “变量ID”表示数据的类型,如“客户状态”或“缺陷代码”或任何您需要的数据。然后有几个条目,每个条目都填充了相应的数据类型列。因此,对于状态,您将有几个条目填写了“char_value”。