我的应用程序有几个表:一个主OBJECT表和几个 用于存储特定种类对象的表:CAT,SHOE和BOOK。
以下是表格列的外观:
object_id (primary key)
object_type (string)
cat_id (primary key)
object_id (foreign key)
name (string)
color (string)
shoe_id (primary key)
object_id (foreign key)
model (string)
size (string)
book_id (primary key)
object_id (foreign key)
title (string)
author (string)
从用户的角度来看,主要识别每个特定对象 按名称,每个表的列不同。对于CAT表 它的名字,对于SHOE表它的模型,以及它的BOOK表 标题。
假设我在没有预先知道什么样的情况下交了一个object_id 它代表的对象 - 猫,鞋或书。我怎么写一个 SELECT语句获取此信息?
显然它看起来有点像这样:
SELECT object_type,name FROM object WHERE object_id = 12345;
但是如何在“名称”栏中找到正确的内容?
答案 0 :(得分:8)
您好像在描述用户对数据的看法(对象有名称,我不关心它们是什么类型)与您用来存储数据的模型不同的场景。
如果是这种情况,假设您对数据库对象有一定的控制权,我可能会创建一个VIEW
,允许您为每种类型的对象合并类似的数据。
SQL Server上的示例:
CREATE VIEW object_names AS
SELECT object_id, name FROM cat
UNION ALL
SELECT object_id, model AS name FROM shoe
UNION ALL
SELECT object_id, title AS name FROM book
GO
然后,您可以SELECT name FROM object_names WHERE object_id = 12345
,而不必考虑基础列名称。
答案 1 :(得分:1)
你唯一真正的解决方案基本归结为同样的事情:为每个特定的表编写显式语句,并union
将它们组合成一个结果集。
您可以在视图中执行此操作(为您提供可以查询的动态数据库对象)或作为查询的一部分(无论是直接SQL还是存储过程)。您没有提到您正在使用的数据库,但基本查询是这样的:
select object_id, name from cat where object_id = 12345 union all
select object_id, model from shoe where object_id = 12345 union all
select object_id, title from book where object_id = 12345
对于SQL Server,创建视图的语法为:
create view object_view as
select 'cat' as type, object_id, name from cat union all
select 'shoe', object_id, model from shoe union all
select 'book', object_id, title from book
您可以查询:
select type, name from object_view where object_id = 12345
但是,你所拥有的是一个基本的表继承模式,但它实现得不正确,因为:
cat
,shoe
,book
)的主键也应该是父表(object
)的外键。你不应该有一个不同的密钥,除非两个cat
记录可以代表相同的object
(在这种情况下,这根本不是继承)object
,因为所有对象都具有“名称”的概念)。 / LI>
答案 2 :(得分:0)
答案 3 :(得分:0)
你做不到。为什么不将它们命名为相同的东西,或者将该名称拉回OBJECT
表。您可以非常轻松地创建名为Name
的列,并将其放在OBEJCT
表中。这仍然会正常化。
答案 4 :(得分:0)
看起来你有几个选择。您可以使用配置文件或“架构”表。您可以重命名表,以便ye列的名称始终相同。您可以让代码中的类知道它的表。您可以使您的架构不那么通用,并允许数据访问层理解它正在访问的数据。
选择哪个?你在解决什么问题?您解决了什么问题,其解决方案是否产生了这个问题?
答案 5 :(得分:0)
如果没有先SELECT
找出kind
,然后SELECT
第二次获取实际数据,就没有办法做到这一点。如果你只有几种不同类型的对象,你可以用一个SELECT
和一堆LEFT JOIN
来同时加入所有表,但如果你不能很好地扩展它有很多木工桌。
但是只是稍微考虑一下,用户看到的“标识符”是否与表中的主键完全对应?你能在标识符本身中编码对象的“种类”吗?因此,例如,如果object_id
12345是鞋子,您可以从用户的角度将其“编码”为“S12345”。一本书是“B4567”和一只猫“C2578”。然后在你的代码中,只需将第一个字母分开并使用它来决定加入哪个表,剩下的数字就是你的主键。
答案 6 :(得分:0)
如果由于依赖性而无法更改原始表,则可以使用统一列名创建表的视图。有关如何创建视图的更多信息,请参见here。
答案 7 :(得分:0)
您可以查看一个表,告诉您数据库中所有表(和列属性)的属性。
在postgres中这类似于pg_stat_alltables,我认为在sql server中有类似的东西。您可以查询并找出所需内容,然后根据该信息构建查询...
编辑:抱歉重读这个问题,我认为这不是你所需要的。 - 我之前通过一个代理键表解决了一个类似的问题 - 一个表包含所有id和一个类型id,然后是一个包含该表主键的串行/标识列 - 这是你应该使用的id ...然后您可以创建一个视图,该视图根据该表中的类型ID查找其他信息。 'entity ref'表将包含列'entityref'(PK),'id','type id'等...(假设你无法重组以使用继承)