Possible to do a MySQL foreign key to one of two possible tables?

后端 未结 5 1135
渐次进展
渐次进展 2020-11-22 06:11

Well here\'s my problem I have three tables; regions, countries, states. Countries can be inside of regions, states can be inside of regions. Regions are the top of the fo

5条回答
  •  刺人心
    刺人心 (楼主)
    2020-11-22 06:32

    I realize that this thread is old, but I saw this and a solution came to mind and I thought I'd throw it out there.

    Regions, Countries and States are Geographical Locations that live in a hierarchy.

    You could avoid your problem altogether by creating a domain table called geographical_location_type which you would populate with three rows ( Region, Country, State).

    Next, instead of the three location tables, create a single geographical_location table that has a foreign key of geographical_location_type_id (so you know if the instance is a Region, Country or State).

    Model the hierarchy by making this table self-referencing so that a State instance holds the fKey to its parent Country instance which in turn holds the fKey to its parent Region instance. Region instances would hold NULL in that fKey. This is no different than what you would have done with the three tables (you would have 1 - many relationships between region and country and between country and state) except now it's all in one table.

    The popular_user_location table would be a scope resolution table between user and georgraphical_location (so many users could like many places).

    Soooo …

    CREATE TABLE [geographical_location_type] (
        [geographical_location_type_id] INTEGER NOT NULL,
        [name] VARCHAR(25) NOT NULL,
        CONSTRAINT [PK_geographical_location_type] PRIMARY KEY ([geographical_location_type_id])
    )
    
    -- Add 'Region', 'Country' and 'State' instances to the above table
    
    
    CREATE TABLE [geographical_location] (
       [geographical_location_id] BIGINT IDENTITY(0,1) NOT NULL,
        [name] VARCHAR(1024) NOT NULL,
        [geographical_location_type_id] INTEGER NOT NULL,
        [geographical_location_parent] BIGINT,  -- self referencing; can be null for top-level instances
        CONSTRAINT [PK_geographical_location] PRIMARY KEY ([geographical_location_id])
    )
    
    CREATE TABLE [user] (
        [user_id] BIGINT NOT NULL,
        [login_id] VARCHAR(30) NOT NULL,
        [password] VARCHAR(512) NOT NULL,
        CONSTRAINT [PK_user] PRIMARY KEY ([user_id])
    )
    
    
    CREATE TABLE [popular_user_location] (
        [popular_user_location_id] BIGINT NOT NULL,
        [user_id] BIGINT NOT NULL,
        [geographical_location_id] BIGINT NOT NULL,
        CONSTRAINT [PK_popular_user_location] PRIMARY KEY ([popular_user_location_id])
    )
    
    ALTER TABLE [geographical_location] ADD CONSTRAINT [geographical_location_type_geographical_location] 
        FOREIGN KEY ([geographical_location_type_id]) REFERENCES [geographical_location_type] ([geographical_location_type_id])
    
    
    
    ALTER TABLE [geographical_location] ADD CONSTRAINT [geographical_location_geographical_location] 
        FOREIGN KEY ([geographical_location_parent]) REFERENCES [geographical_location] ([geographical_location_id])
    
    
    
    ALTER TABLE [popular_user_location] ADD CONSTRAINT [user_popular_user_location] 
        FOREIGN KEY ([user_id]) REFERENCES [user] ([user_id])
    
    
    
    ALTER TABLE [popular_user_location] ADD CONSTRAINT [geographical_location_popular_user_location] 
        FOREIGN KEY ([geographical_location_id]) REFERENCES [geographical_location] ([geographical_location_id])
    

    Wasn't sure what the target DB was; the above is MS SQL Server.

提交回复
热议问题