【问题标题】:My World_Time DataBase design/ORM我的世界时间数据库设计/ORM
【发布时间】:2012-08-18 12:19:45
【问题描述】:

我有一个数据库设计,我想获得一些反馈/帮助。

我有 3 个不同的实体:CitiesTimeZonesRules

  • City 与 1 相关联,并且仅与 1 个 TimeZone 相关联(不是 1:只有 1)
  • TimeZone 可能与许多Cities 相关联(不确定城市的最小数量)。
  • TimeZone 正好有 2 个Rules(DST 和 ST)。
  • 每个Rule 可能与许多不同的TimeZones 相关联

我使用 ORM 设计器设计我的表格只是为了帮助我进行可视化:

在这个 ORM 中,有:

  • TimeZones 和子 Cities 之间的一对多关系
  • TimeZones 和子 TimeZoneRule 之间的一对多关系
  • Rule 和子TimeZoneRule 之间的一对多关系

现在回答我的问题:

  • 这种多对多连接表可以工作吗?

  • 我怎么知道Rule 属于什么TimeZone?我有TimeZone.RuleName 属性来获取RuleTimeZone 但是如果我想倒退,说找到所有适用于规则的TimeZones

  • 我如何使用字符串 (RuleName) 来查找 TimeZone 的 Rule,因为 TimeZone 有 2 条规则(名称相同但 ID 不同/唯一)。

  • 如何使用正确的 ID/行填充此联结表?

  • 我知道City 有一个TimeZoneId,我为其添加了实际值,我可以使用这个TimeZoneId 来查找TimeZoneCity 所属,但我怎么能找到所有CitiesTimeZone 包含?

下面我粘贴了我为创建这些表而编写的 TSQL 代码,我唯一没有的是关联,因为我从未在 TSQL 中建立关联(很明显)。

            USE World_Time

            IF OBJECT_ID('timezones', 'U') IS NOT NULL
                DROP TABLE timezones;
            IF OBJECT_ID('rules', 'U') IS NOT NULL
                DROP TABLE rules;
            IF OBJECT_ID('leaps', 'U') IS NOT NULL
                DROP TABLE leaps;
            IF OBJECT_ID('cities', 'U') IS NOT NULL
                DROP TABLE cities;
            IF OBJECT_ID('timezone_rule', 'U') IS NOT NULL
                DROP TABLE timezone_rule;

            CREATE TABLE timezones
            (
                [id] INT NOT NULL PRIMARY KEY,
                [name] VARCHAR(30) NOT NULL,
                [bias] SMALLINT NOT NULL,
                [rule_name] VARCHAR(10),
                [tz_abreviation] VARCHAR(7) NOT NULL,
                [country_code] CHAR(2) NOT NULL,
                [country_name] VARCHAR(42) NOT NULL,
                [comments] VARCHAR(100),
                [coordinates] VARCHAR(20),
                [version] ROWVERSION
            );

            CREATE TABLE rules
            (
                [id] INT NOT NULL IDENTITY PRIMARY KEY,
                [name] VARCHAR(10) NOT NULL,
                [bias] SMALLINT NOT NULL,
                [start_year] SMALLINT NOT NULL,
                [end_year] SMALLINT NOT NULL,
                [month] TINYINT NOT NULL,
                [date] VARCHAR(7) NOT NULL,
                [time] TIME(0) NOT NULL,
                [time_type] CHAR(1),
                [letter] CHAR(1),
                [version] ROWVERSION
            );

            CREATE TABLE leaps
            (
                [id] INT NOT NULL IDENTITY PRIMARY KEY,
                [year] SMALLINT NOT NULL,
                [month] VARCHAR(3),
                [day] SMALLINT NOT NULL,
                [time] TIME(0) NOT NULL,
                [correction] VARCHAR(1) NOT NULL,
                [rs] VARCHAR(1) NOT NULL,
                [version] ROWVERSION
            );

            CREATE TABLE cities
            (
                [id] INT NOT NULL IDENTITY PRIMARY KEY,
                [name] VARCHAR(200) NOT NULL,
                [ascii_name] VARCHAR(200),
                [alternate_names] VARCHAR(5000),
                [latitude] FLOAT(24),
                [longitude] FLOAT(24),
                [feature_class] CHAR(1),
                [feature_code] VARCHAR(10),
                [country_code] CHAR(2) NOT NULL,
                [country_code2] VARCHAR(60),
                [population] BIGINT,
                [elevation] INT,
                [modification_date] DATETIME NOT NULL,
                [admin1code] VARCHAR(20),
                [admin2code] VARCHAR(80),
                [admin3code] VARCHAR(20),
                [admin4code] VARCHAR(20),
                [gtopo30] INT,
                [timezone_id] INT NOT NULL,
                [timezone_name] VARCHAR(60) NOT NULL,
                [version] ROWVERSION
            );

            CREATE TABLE timezone_rule
            (
                [timezone_id] INT NOT NULL,
                [rule_id] INT NOT NULL,
                PRIMARY KEY (timezone_id, rule_id),
                [version] ROWVERSION
            );

            -- Is this how I would populate the junction table?
            --INSERT INTO timezone_rule
            --  (timezone_id)
            --SELECT id
            --FROM timezones;
            --INSERT INTO timezone_rule
            --  (rule_id)
            --SELECT id
            --FROM rules;

对于我几个月来一直试图这样做的可怕帖子,我很抱歉,我厌倦了每天几个小时的 Binging/谷歌搜索:P 感谢您花时间阅读,非常感谢/

-弗朗西斯科

【问题讨论】:

    标签: sql orm foreign-keys many-to-many relation


    【解决方案1】:

    我将跳过关于您是否真的需要/应该这样做而不是使用标准库的部分,而只是解决时区映射到两个规则的问题。

    Timezone 有一个RuleId。它可以有两个RuleIds:

    • DstRuleId
    • StRuleId

    例如:

            CREATE TABLE timezones
            (
                [id] INT NOT NULL PRIMARY KEY,
                [name] VARCHAR(30) NOT NULL,
                [bias] SMALLINT NOT NULL,
    
                [dst_rule_id] INT,
                [st_rule_id]  INT,
    
                [tz_abreviation] VARCHAR(7) NOT NULL,
                [country_code] CHAR(2) NOT NULL,
                [country_name] VARCHAR(42) NOT NULL,
                [comments] VARCHAR(100),
                [coordinates] VARCHAR(20),
                [version] ROWVERSION
            );
    

    那将是最简单的。为了获得更大的灵活性,并沿着更关系的路线走下去,可以引入一个RuleType 表,该表仅以两个条目开头:

    • 夏令时
    • ST

    这将允许将来扩展规则。但是您需要从Rule 表到RuleType 表的映射,而TimeZoneRule 表将引用这些映射。如果确信这不会改变,则使用 DstRuleId 和 StRuleId 会更容易。

    • 找到规则适用的所有时区?

      SELECT timezoneid FROM TimeZoneRule WHERE RuleId = ?

    • 我如何使用字符串 (RuleName) 来查找 TimeZone 的规则,因为 TimeZone 有 2 个规则(名称相同但 ID 不同/唯一)。

      如果 TimeZoneRule 中有两列,则为隐式

    • 如何使用正确的 ID/行填充此联结表?

      INSERT INTO timezone_rule(timezone_id, rule_id) VALUES (?, ?)

    • 我知道 City 有一个 TimeZoneId,我为其添加了实际值,我可以使用这个 TimeZoneId 来查找某个 City 所属的 TimeZone,但是如何找到一个 TimeZone 包含的所有 Cities?

      SELECT id FROM city WHERE timezone_id = ?

    【讨论】:

    • 我不使用标准库的原因是因为这将是 Windows Phone 应用程序上的本地数据库,不幸的是,它不包含库。
    猜你喜欢
    • 1970-01-01
    • 2012-03-21
    • 2021-07-24
    • 2011-04-15
    • 2013-08-19
    • 1970-01-01
    • 1970-01-01
    • 2010-09-29
    • 2021-07-26
    相关资源
    最近更新 更多