duanan1946 2014-09-10 13:38
浏览 22
已采纳

MySQL唯一密钥方案

I have a table that is consisted of the following columns:

Table name: User

Columns: {id, fk1, fk2, username}

id: is the primary key

fk1 and fk2 are foreign keys coming from other tables

There are 2 cases:

1) fk1 + username = unique value

2) fk2 + username = unique value

For example:

fk1 = the id of a country in the country table

fk2 = the id of a state in the state table

In countries that have states (ex. USA)

What i want is the username of the user to be only unique inside a state. Two users from different states can have the same username, but not in the same state.

In countries with no states (ex. Spain)

Two users from the same country cannot have the same username. Two users from different countries can have the same username.

So, if the user registered is coming from a country having states i need to create a unique index for columns fk2 and username. [ensure uniqueness per state]

If the user registered is coming from a country with no states i need to create a unique index for columns fk1 and username. [ensure uniqueness per country]

What i did so far was to create a table for users coming from states and a table for users coming from a country with no states. Like below:

--Table name: User_States

Columns: {id, fk2, username}

Unique index on fk2 + username

--Table name: User

Columns: {id, fk1, username}

Unique index on fk1 + username

This solution can work by filtering the users (users from state or not) before inserting the data into each table. But i want only one table with all users and not two, because when i want to check if for example an email is already registered by a user (either in states or not) i have to perform 2 queries (one in each table). Or if i want to extract a list of all usernames like "darklord", regardless of their location, again i have to perform 2 queries.

Is there a way to have this? If yes, how will the table look like? My problem starts when the user comes from a country with no states, since the fk2 column is going to be empty. I know that a unique index allows Null value but only one Null value.

Also one general question: How can i check if a single query on a big table is faster/slower than 2 queries on 2 smaller tables?

PS: The storage engine i am using is InnoDB

Thanks in advance.

  • 写回答

1条回答 默认 最新

  • dourong8495 2014-09-10 14:07
    关注

    Something like this work?

    create table #Something
    (
        SomeDataField varchar(10) not null,
        CountryCode char(3) not null,
        StateCode char(2) null,
        CONSTRAINT UniqueCountryState UNIQUE NONCLUSTERED
        (
            SomeDataField, CountryCode, StateCode
        )
    )
    
    insert #Something
    select 'Value1', 'USA', 'NY' union all
    select 'Value1', 'CAN', null union all
    select 'Value1', 'MEX', null union all
    select 'Value1', 'USA', 'AK'
    

    Now try inserting any of those values again and it will fail because the combination already exists.

    insert #Something
    select 'Value1', 'USA', 'NY'
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 C#算法问题, 不知道怎么处理这个数据的转换
  • ¥15 YoloV5 第三方库的版本对照问题
  • ¥15 请完成下列相关问题!
  • ¥15 drone 推送镜像时候 purge: true 推送完毕后没有删除对应的镜像,手动拷贝到服务器执行结果正确在样才能让指令自动执行成功删除对应镜像,如何解决?
  • ¥15 求daily translation(DT)偏差订正方法的代码
  • ¥15 js调用html页面需要隐藏某个按钮
  • ¥15 ads仿真结果在圆图上是怎么读数的
  • ¥20 Cotex M3的调试和程序执行方式是什么样的?
  • ¥20 java项目连接sqlserver时报ssl相关错误
  • ¥15 一道python难题3