我希望你能帮我解决这个问题。我使用伪代码来使一切变得简单。
我有一个描述位置的表格。
location_table
location = charfield(200) # New York, London, Tokyo
产品经理现在希望位置如下所示:
Global = select every location
Asia = select every location in Asia
US = select every location in US
Current system = London (etc.)
这是我提议的重新设计。
location_table
location = charfield(200) # New York, London, Tokyo
continent = foreign key to continent_table
continent_table
continent = charfield(50) # "None", "Global", Asia, Europe
但这看起来很可怕。这意味着在我的代码中,我总是需要检查客户使用的是"global“还是"none",然后选择相应的位置记录。例如,到处都会有这样的代码:
get continent
if continent is global, select everything from location_table
else if continent is none, select location from location_table
else select location from location_table where foreign key is continent
我的感觉是这是一个已知的问题,并且有一个已知的解决方案。有什么想法吗?
谢谢。
发布于 2016-11-17 08:41:54
使用级别:
0 -> None
00 -> Global
001 -> Europe
002 -> Asia
003 -> Africa
select location from location_table where continent like '[value]%'
使用固定长度代码,您可以为区域添加前缀,然后为区域内的区域再添加一个数字,依此类推。
好的,让我试着改进一下。
考虑世界,它有最低级别(或最高级别取决于你如何看待它)
World ID = '0' (1 digit)
现在,选择您想要如何划分世界:(大陆,半大陆,...)并指定下一级。
Europe ID = '01' (First digit World + Second digit Europe)
Asia ID = '02'
America ID = '03'
...
下一级:国家。(至少2位数字)
England ID = '0101' (World + Continent + Country)
Deutchland ID = '0102'
....
Texas ID = '0301'
....
下一级:区域(2位)
Yorkshire ID = '010101' (World + Continent + Country + Region)
....
下一级:城市(2位或3位)
London ID = '01010101' (World + Continent + Country + Region + City)
诸若此类。
现在,无论哪个区域都可以使用相同的SELECT some_aggregate, statistics, ... FROM ...
,只需更改:
WHERE Region like '0%' --> The whole world
WHERE Region like '02%' --> Asia
WHERE Region like '01010101%' --> London
WHERE Region like '02%' AND Region like '01%' --> Asia & Europe
发布于 2016-11-17 08:42:27
您在这里看到的似乎是一组位置,然后是一组位置组。这些组可以是所有位置(全局),也可以是它们的子集。
您可以使用位置之间的中间表和关联位置和位置集的新位置集表来构建此表。
您可以构建位置集表和连接表,以便各个位置也是位置集,但这些位置仅连接到一个位置。这样,所有的位置选择都来自一个表--位置集。
因此,您最终得到了三种不同类型的位置集:
映射1:1的所有("global")
可以想象,这可以被创建为一个层次结构,但这些查询效率可能很低,因为优化器往往看不到联接基数。
发布于 2016-11-17 09:07:41
您可以使用层次结构和自引用外键来实现这一点,例如
LocationID Name ParentLocationID LocationType
------------------------------------------------------------------
1 Planet Earth NULL Planet
2 Africa 1 Continent
3 Antartica 1 Continent
4 Asia 1 Continent
5 Australasia 1 Continent
6 Europe 1 Continent
7 North America 1 Continent
8 South America 1 Continent
9 United States 7 Country
10 Canada 7 Country
11 Mexico 7 Country
12 California 9 State
13 San Diego 12 City
14 England 6 Country
15 Cornwall 14 County
16 Truro 15 City
分层数据通常需要递归或多个连接才能获得所有级别,this answer包含比较主要数据库管理系统性能的文章的链接。
许多DBMS现在支持递归公用表表达式,由于没有指定DBMS,因此我将使用SQL Server语法,因为它是我最熟悉的语法,下面是一个简单的示例。
DECLARE @LocationID INT = 7; -- NORTH AMERICA
WITH LocationCTE AS
( SELECT l.LocationID, l.Name, l.ParentLocationID, l.LocationType
FROM dbo.Location AS l
WHERE LocationID = @LocationID
UNION ALL
SELECT l.LocationID, l.Name, l.ParentLocationID, l.LocationType
FROM dbo.Location AS l
INNER JOIN LocationCTE AS c
ON c.LocationID = l.ParentLocationID
)
SELECT *
FROM LocationCTE;
基于上述示例数据的输出
LocationID Name ParentLocationID LocationType
-----------------------------------------------------------------
7 North America 1 Continent
9 United States 7 Country
10 Canada 7 Country
11 Mexico 7 Country
12 California 9 State
13 San Diego 12 City
为location ID提供值1 (Planet Earth)将返回整个表,或者提供locationID 11 (墨西哥)将仅返回这一行,因为示例数据中没有比这更小的行。
https://stackoverflow.com/questions/40649951
复制