在MS Access中创建查找字段 - 更好地拥有一个或多个源表?

时间:2011-12-01 19:51:25

标签: ms-access

我正在创建一个数据库来跟踪Access 2010中的参与者。

主要数据存储在名为ParticipantMaster的表中。

我在ParticipantMaster中有几个字段要将查找值分配给。

学校(MLK High,Central High,Northeast High ...)

兴趣(视觉艺术,戏剧,体育,文学......)

颜色(红色,蓝色,绿色......)

我可以创建一个表School,另一个表Interests,另一个表Color,然后让每个表的来源为SELECT Color.ColorName FROM Color然后SELECT School.SchoolName FROM School然后SELECT Interests.InterestPicker from Interest ...这就是我平时做事的方式。

然后我想知道如果不是三个单独的表,我可以有一个名为ParticipantData的表,其中包含名为School,Interests,Color ...的字段,然后我的查询查询为SELECT ParticipantData.School from ParticipantData,{{1} }和SELECT ParticipantData.Interests FROM ParticipantData

这种方式有哪些优点/缺点?

3 个答案:

答案 0 :(得分:2)

我已经尝试了第二种方法并且它不是太糟糕,但最后,我希望我已经使用了第一种方法。控制和添加新项目要容易得多。

我希望你不打算在你的牌桌上查看。

答案 1 :(得分:2)

您描述的查找表有点独特。大多数人都不建议你这样做。

    ParticipantData
 +-----------------------+
 | School    (text)      |
 | Color     (text)      |
 | Interests (text)      |
 +-----------------------+

下面的内容更有意义

    ParticipantData
 +-----------------------+
 | ID (AutoNumber)       |
 |-----------------------|
 | LookupType (number)   |
 | LookupValue (text)    |
 +-----------------------+

拥有像这样的单个表的主要缺点是

  1. 很难让外键约束完美。例如您希望将ParicipantMaster.Color限制为仅与LookupType颜色对应的ID,但您可以做的最好是将其限制为Participant Data表中的ID。

  2. 如果只想为一个LookupType添加属性,那就太痛苦了。例如,你想将SchoolDistrict添加到学校的LookupType中,你有很多不受欢迎的选择。 (A.允许schoolDistrict成为一个颜色的归属.B。从查找表中删除学校并修复所有代码,C。添加一个链接到参与者表的表)

答案 2 :(得分:1)

我实际上结合了两种方法。我现在要警告你,这可能是啰嗦,可能会有点矫枉过正。但是,我发现这是一个很好的通用解决方案,非常好地扩展

该方法共包含四个表:

PDLists (local to the front-end)
--------
K*PDListID        Long          
 *PDListName      Text (50)     
  CodeLen         Long          
 *UserCanEdit     Boolean [False]             
 *HasActiveCheck  Boolean [False]             

PDChoices (linked to the back-end)
---------
K*PDChoiceID  Long AUTONUMBER             
 *PDListID    Long          
  PDCode      Text (10)     
 *PDDesc      Text (255)    
 *Seq         Long          
 *IsActive    Boolean [True]

PDChoicesLocked (local to the front-end)
---------------
K*PDChoiceID  Long AUTONUMBER             
 *PDListID    Long          
  PDCode      Text (10)     
 *PDDesc      Text (255)    
 *Seq         Long          
 *IsActive    Boolean [True]              

PDFields (local to the front-end)
--------
K*PDListID    Long          
K*TblName     Text (50)     Used to enforce referential integrity for fields that use code:description pair & to restrict length of text entry
K*FldName     Text (50)     Used to enforce referential integrity for fields that use code:description pair & to restrict length of text entry

传奇:K:主键; *:必填字段; [Foo]:默认值

PDLists

第一个表的每个查找表都有一个条目。 CodeLen(代码长度)字段用于要存储有意义缩写的查找。例如,您可以为查询设置CodeLen = 1,例如:N: North; E: East; S: South; W: West

如果UserCanEdit为True,则下拉选项存储在后端表PDChoices中。否则,它们存储在本地表PDChoicesLocked中。

我有一个帮助函数,它生成要在组合框中使用的SQL语句。我将它传递给PDListID,它检查CodeLen和UserCanEdit字段以创建适当的SELECT语句。辅助函数只是将其打印到即时窗口,然后将其复制并粘贴到我需要的位置。

PDListID   PDListName            CodeLen   UserCanEdit   HasActiveCheck
   1       Cardinal Directions      1          True          False

PDChoices / PDChoicesLocked

这两个表之间的唯一区别在于它们的位置(如上所述)。我可以在后端将两个表合并为一个表,但是将本地锁定表意味着我可以在开发期间更改此表,并且即使我将程序部署到不同的客户端也可以保证其内容。

Seq(序列)字段用于允许自定义排序选项。 IsActive字段允许在下拉列表中隐藏选项,而不会丢失参照完整性,如果这些查找当前正在使用中。

PDChoiceID    PDListID    PDCode    PDDesc    Seq    IsActive
    1             1         N       North      1        True
    2             1         E       East       3        True
    3             1         S       South      2        True
    4             1         W       West       4        True

PDFields

此表用于强制引用完整性。这实际上无法在数据库级别完成,因此它以用户可用于更改下拉选项的形式强制执行。

PDListID   TblName           FieldName
   1       StreetAddresses   CardinalDirection
   1       Locations         CompassPoint

Pulldowns Form

当用户双击具有用户可编辑选项的组合框(即UserCanEdit=True)时,将加载Pulldown表单。表单标题设置为PDListName。如果CodeLen不为null,则查找代码的文本框可见。如果HasActiveCheck=True,则会显示一个复选框,允许用户切换各个下拉选项的有效状态。

我有一个自定义函数,可以根据PDCode限制可以输入CodeLen字段的字符数。但是,如果CodeLen为null,那么我会检查是否需要限制PDDesc字段的长度。例如,如果字段的字段类型为Long,那么我假设我在字段中保存PDChoiceID,并且我不限制PDDesc的长度。但是如果引用的字段是Text / Varchar字段,那么我得到该字段的长度并相应地限制PDDesc的长度。

当Pulldowns表格关闭时,我会重新询问用户双击的组合框,以便他们可以立即访问他们添加的任何新选项。

摘要

这种方法有一个主要的缺点:最初设置它是很多工作。但是,很多工作是在后端提供用户可编辑的表,以及允许用户更新这些选择的表单。如果你坚持使用三个本地表,你就可以获得可扩展性和灵活性而无需大量工作。

<强>赞成

  • 灵活;值可以多种方式存储在主表中
    • by PDChoiceID
    • by PDCode
    • by PDDesc
  • 可扩展;初始设置完成后,添加新查找非常简单
  • 强大;
    • 可以通过设置IsActive=False
    • 从裁减中删除选项而不删除
    • 项目的排序顺序是完全可自定义的
    • 您可以提供一个界面,让用户在不牺牲参照完整性的情况下对列表进行更改

<强>缺点

  • 最初设置比你提出的两个选项更多的工作
  • 您无法在数据库层强制执行参照完整性;我不认为这是一个主要的Con,因为如果你小心,你仍然可以在应用层强制执行参照完整性

最后一点。我意识到Access 2007引入了一项功能,允许用户将项添加到组合框中。从开发人员的角度来看,该功能是无用的,因为更改存储在前端(并且它不提供参照完整性)。我的方法将这些更改存储在后端(它们所属的位置)中,尽管Access 2007的新功能,我仍继续使用它。