数据库中列的多个值

时间:2010-01-18 15:59:10

标签: java database

是否可以在数据库列中存储多个值。如果是,我应该使用哪种类型?并通过我的java代码如何插入值。

例如,我希望有一个“语言”列,可以存储单行的java,c ++,c#等值。

编辑:我希望有一个名为student的表,其中包含有关列的学生的所有信息,以存储他所知道的语言名称。

8 个答案:

答案 0 :(得分:9)

您应该创建一个包含您要使用的所有不同语言的表“language”,然后使用外键从另一个表的LanguageID列链接到此表。

编辑:如果您希望给定记录使用多种语言,则还需要创建一个链接表,将记录链接到给定的LanguageID。然后,您可以通过在链接表中创建新记录,为给定记录放入任意数量的不同语言。

答案 1 :(得分:5)

在单个列中存储多个值通常不是一个好主意,因为它违反了database normalization的原则。

根据您的描述,您似乎拥有多对多的关系。通过在列中存储多个值来实现它会强制您在需要更新列或按语言查询时更加努力地工作。

技术上可以考虑一种解决方法(例如,Telcontar建议),但我建议您阅读一些关于不同正常形式的内容,并重新考虑数据库设计。

答案 2 :(得分:2)

如果您了解数据库设计并希望摆脱这种额外的语言表,这是通常的“好”方法,您可以使用例如字符串。

在字符串中保留与“en-en”(第一个国家,第二语言变体“)一样的ISO语言代码以及分隔符标记,显然空间​​可能是一个好的,所以”en-en de- de“for english and german。

然后,您可以在此字符串列上使用“like”运算符进行复杂的多语言匹配。

如果您是专业人士并且知道自己在做什么,可以将其称为优化。如果你是一个新手,那么你显然不知道你做了什么以及关系数据库系统中的“关系”是什么意思。

答案 3 :(得分:2)

使用连接表(也称为链表)来定义n-m关系。

用户表(伪SQL):

CREATE TABLE user {
    id INTEGER GENERATED PRIMARY KEY,
    name VARCHAR
}

语言表(伪SQL):

CREATE TABLE language {
    id INTEGER GENERATED PRIMARY KEY,
    name VARCHAR
}

加入用户和语言表(伪SQL):

CREATE TABLE user_language {
    user_id INTEGER FOREIGN KEY REFERENCES user(id),
    language_id INTEGER FOREIGN KEY REFERENCES language(id)
}

通过这种方式,您可以按用户ID(以及与特定语言绑定的所有用户)获取所有语言。一些RDBMS支持将这些值检索为SQL ARRAY类型,而您可以在单个查询中通过ResultSet#getArray()获取这些类型。例如,在PostgreSQL中,您可以执行以下查询:

SELECT u.id, u.name, ARRAY(
    SELECT l.name
    FROM language l
    JOIN user_language ul ON u.id = ul.user_id
    WHERE l.id = language_id) AS languages
FROM user u
您可以在JDBC中处理

,如下所示:

while (resultSet.next()) {
    Long id = resultSet.getLong("id");
    String name = resultSet.getString("name");
    Object[] languages = resultSet.getArray("languages").getArray();
    // Cast to String[] or convert to List<String> or so yourself.
}

答案 4 :(得分:1)

你的意思是枚举,只能使用某些值,或者你的意思是在给定行的列中存储多个值?

枚举

-- Works in MySQL for sure
table whatever (
  language enum('JAVA','C++,'C#') NOT NULL DEFAULT 'JAVA'
};

多个值

不要这样做,而是使用多对多关系:

table whatever (
  id int
);
table language (
  id int,
  name varchar(256)
)
table whatever_language)(
  whatever_id int,
  language_id int
)
-- don't forget foreign key constraints

答案 5 :(得分:1)

你需要创建一个Zack所提到的语言表,其中表示每种语言,然后有一个表将它们链接到诸如_-Langage(其中_被原始表名替换)

此链接表将使用增量索引作为其主键,并具有“语言”表的“外键”和“原始”表。然后,链接表中可以有多行用于原始表中所需的每种语言

答案 6 :(得分:0)

我认为Zack的答案是正确的,但是如果你真的需要在数据库行中存储多个值,你可以使用VARCHAR类型并使用像“;”这样的分隔符。要分隔值,但在添加/编辑这些值以正确解析它们时必须小心。

或者,如果您使用的是Oracle数据库,则可以将列的类型定义为ARRAY,但这是一种产生过多依赖关系的专有解决方案,我不建议使用它。

答案 7 :(得分:0)

你所说的是你的桌子(你没有给出名字)和语言之间的多对多关系。
让我假设你的桌子是关于人的,你想跟踪哪些人精通哪种语言 任何给定的人都将精通一种(可能为零)或更多语言。要对此进行建模,您需要三个表:Person,Language和第三个表,它们可能是LanguageProficiency,它引用了一个人和一种语言。在此表中,您可以为同一个人或相同语言创建多个行,但每个人和语言的唯一组合应该只有一个条目(即这两列构成此表的主键)。

在这里使用第三个表格的优势(通过将其连接到文本字段中的其他一些建议)是,很容易将其扩展为包含其他属性,例如一个人使用了多少年语言,或语言掌握程度的评级,或一些测试分数。这些是您想要了解的每个人和语言组合的内容,因此它属于LanguageProficiency表。