外键列名末尾无Id后缀的含义及SQL Server下表创建与约束实现
实现规则说明
无Id后缀的外键列处理逻辑
列名末尾必须加Id后缀是课程约定的命名规范,并非SQL Server的语法强制要求,也不是判定外键的标准。
判定一列是否为外键的唯一依据是:该列存储的值是否指向其他表(或本表)的主键值。外键约束的实现只要求「当前列的数据类型与被引用的主键列类型完全匹配」,和列名本身无任何关联。
以evolvesfrom列为例:该列存储宝可梦进化来源的pokemonId值,属于自连接外键,直接按ERD给定的列名定义,按标准语法添加外键约束即可,不需要强行修改列名加Id后缀。
SQL Server 建表示例
pokemon表(含evolvesfrom自外键)
CREATE TABLE pokemon ( pokemonId INT IDENTITY(1, 1), pokemonName VARCHAR(50) NOT NULL, -- 按ERD定义的无Id后缀列名,类型与被引用的pokemonId完全匹配 evolvesfrom INT NULL, CONSTRAINT pk_pokemon_pokemonId PRIMARY KEY (pokemonId), -- 外键约束正常编写,明确指定当前列与被引用列的关联关系即可 CONSTRAINT fk_pokemon_evolvesfrom FOREIGN KEY (evolvesfrom) REFERENCES pokemon(pokemonId) ON DELETE SET NULL -- 可根据业务需求调整删除/更新关联规则 );
pokemonFight表(符合三方依赖业务规则)
对应业务规则「对战经验点函数依赖于宝可梦、对战、对战地点三者」,建表时需要遵循两点:
pokemonfightexppoint是存储对战经验值的普通属性列,本身不关联其他表,不是外键,无需添加外键约束- 对应宝可梦、对战、对战地点的三个关联列,需要组成联合主键,保证同一组「宝可梦+对战+地点」的组合仅对应一条经验值记录,避免重复数据
- 三个关联列无论列名是否带Id后缀,只要类型与对应引用表的主键匹配,正常添加外键约束即可
示例代码:
CREATE TABLE pokemonFight ( -- 按ERD定义的无Id后缀关联列编写 pokemon INT NOT NULL, -- 关联pokemon表的pokemonId fight INT NOT NULL, -- 关联fight表的fightId location INT NOT NULL, -- 关联location表的locationId -- 经验值普通属性列 pokemonfightexppoint INT NOT NULL, -- 联合主键匹配三方依赖的业务规则 CONSTRAINT pk_pokemonFight联合主键 PRIMARY KEY (pokemon, fight, location), -- 外键约束正常添加 CONSTRAINT fk_pokemonFight_pokemon FOREIGN KEY (pokemon) REFERENCES pokemon(pokemonId), CONSTRAINT fk_pokemonFight_fight FOREIGN KEY (fight) REFERENCES fight(fightId), CONSTRAINT fk_pokemonFight_location FOREIGN KEY (location) REFERENCES location(locationId) );
实操注意事项
- 无需为了适配课程的命名规范强行修改ERD给定的列名,只要外键约束的关联关系正确,数据库逻辑就符合要求
- 如果后续有统一命名规范的需求,可自行将无Id后缀的外键列调整为规范命名(如将
evolvesfrom改为evolvesfromPokemonId),这属于设计优化,不是实现约束的必要步骤 - 联合主键的选择完全由业务的函数依赖决定,和列名、是否为外键无关
内容的提问来源于stack exchange,提问作者Rachel D
相关产品推荐
相关产品推荐

