简体   繁体   English

以正确的方式使用PRIMARY KEYS(处理语言环境)

[英]Using PRIMARY KEYS in the right way (handling locales)

I have a table called countries that has the structure: ID, LOCALES_ID, NAME 我有一个名为countries的表格,其结构为:ID,LOCALES_ID,NAME

I want to handle multiple locales with this table, so I need that for different LOCALES_ID, the ID is the same. 我想使用此表处理多个语言环境,因此对于不同的LOCALES_ID,我需要使用相同的ID。 So, if I insert: 所以,如果我插入:

INSERT INTO countries (locales_id, name)
VALUES
('1', 'Lorem'),
('2', 'Ipsum');

The final result I want on the database is: 我想要在数据库上的最终结果是:

ID | LOCALES_ID | NAME
1  | 1          | Lorem
1  | 2          | Ipsum

But with the INSERT I tried I got the next result: 但是我尝试使用INSERT获得下一个结果:

ID | LOCALES_ID | NAME
1  | 1          | Real insert
2  | 2          | Real insert #2

My countries table has a PRIMAY index on the columns ID and LOCALES_ID and I supposed that this was all what I need for when I insert different locales I get the same ID. 我的countries表在ID和LOCALES_ID列上有一个PRIMAY索引,我认为当我插入不同的语言环境而获得相同的ID时,这就是我所需要的。

How I can solve this problem? 我该如何解决这个问题?

Thank you in advance, 先感谢您,

What you're trying to implement here is a one-to-many relationship, ie each Country can have multiple Locales. 您要在此处实现的是一对多关系,即每个国家可以有多个语言环境。 This cannot be achieved with a single table, as you would find yourself with the same Country appearing multiple times. 单个表无法实现此目的,因为您会发现自己所在的国家/地区出现了多次。 What you should do is split the data in two tables. 您应该做的是将数据分成两个表。 You can find an example below. 您可以在下面找到一个示例。

Structure for Countries table 国家结构表
- ID int, autoincrement, primary key -ID int,自动递增,主键
- Name varchar -名称varchar

Structure for Locales table 语言环境表的结构
- CountryID int, primary key -CountryID int,主键
- LocaleID int, primary key -LocaleID int,主键
- Name varchar -名称varchar

Handling INSERT - To insert in Countries table, simply populate Name field (or any other fields you may need): 处理插入-要插入“国家/地区”表,只需填充“名称”字段(或您可能需要的任何其他字段):

INSERT INTO Countries
  (Name)
VALUES
  ('Ireland')

The ID field will be populated automatically. ID字段将自动填充。 For this example, we can imagine that "Ireland" will have ID = 1. 对于此示例,我们可以想象“爱尔兰”的ID = 1。
- To insert in Locales, you'll pass three values, ie CountryID, LocaleID and Name. -要在语言环境中插入,您将传递三个值,即CountryID,LocaleID和Name。

INSERT INTO Locales
  (CountryID, LocaleID, Name)
VALUES
  (1, 1, 'Lorem')

This query will insert LocaleID for the Country with ID = 1 (ie Ireland) and 'Lorem' as a name. 该查询将为ID = 1(即爱尔兰)和“ Lorem”作为名称的国家/地区插入LocaleID。 To insert 'Ipsum', you'll do the same: 要插入“ Ipsum”,您将执行以下操作:

INSERT INTO Locales
  (CountryID, LocaleID, Name)
VALUES
  (1, 2, 'Ipsum')

Where LocaleID will be 2, for Country with ID = 1 and name will be 'Ipsum'. 对于ID = 1的国家/地区,LocaleID为2,名称为'Ipsum'。

How to retrieve the data 如何检索数据
Since now data is split in two tables, you'll have to use a Join to put it together. 由于现在将数据分为两个表,因此您必须使用Join将它们放在一起。 It's very simple: 很简单:

SELECT
  C.ID AS CountryID
  ,L.Name AS CountryName
  ,L.LocaleID
FROM
  Countries C
  LEFT JOIN
  Locales L ON
    (L.CountryID = C.CountryID) AND
    (L.LocaleID = :InputLocaleID)

That's it. 而已。 Now your query will return the Country with its name in the proper Locale, if it exists. 现在,如果存在,查询将以正确的语言环境返回其名称所在的国家/地区。 If it doesn't, CountryName and LocaleID will be NULL. 如果不是,CountryName和LocaleID将为NULL。

Update 2012/08/11 - How to use a single table (not recommended) 更新2012/08/11-如何使用单个表(不推荐)

If you wish to use a single table for the Countries, you'll have to handle the Country IDs manually. 如果您希望对国家/地区使用单个表,则必须手动处理国家/地区ID。 That is, you'll perform an INSERT as follows: 也就是说,您将按以下方式执行INSERT:

INSERT INTO Countries
  (ID, LocaleID, Name)
VALUES
  (:CountryID, :LocaleID, :Name)

This, however, will leave you with an issue. 但是,这将给您带来问题。 Imagine the table contains an unspecified number of Countries and you have to add a new one. 假设该表包含一个未指定的国家/地区,而您必须添加一个新的国家/地区。 What ID would you give to this new Country? 您会给这个新国家/地区提供什么ID?

Perhaps some thing like 也许像

Locales
(LocalID, LocaleName) Use the standard id e.g. en-GB
Primary Key (LocaleID)

Countries (might have to work on this bit for countries like Belgium (Waloon and Flemish) 国家(可能必须为比利时(瓦隆和佛兰芒)等国家在这方面做出努力

(CountryID,CountryLocaleID)
Primary Key (CountryID)
ForeignKey CountryLocaleID -> Locales(LoacleID)

(add any other country specific info, but not the name! (添加其他任何特定于国家/地区的信息,但不要添加名称!

CountryTranslations
(CountryID, LocaleID,InternationalisationID) 
Primary Key(CountryID,LocaleID) 
Unique Key(InternationalisatiosnID)
Foreign Key CountryID -> Countries.CountryID
Foreign Key LocaleID -> Locales.LocaleID
Foreign Key InternationalisationID -> Internationalisations.InternationalisationID

(This is your link between country and it's name in various Locales (这是您在各个国家/地区和国家/地区名称之间的链接

Internationalisations
(InternationalsationID, Translation)
PK (InternationalisationID)

(All your translations.) (所有翻译。)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM