mysql有没有数组

WBOY
WBOY 转载
2023-06-03 12:04:36 621浏览

MySQL中无数组类型,通常将数组元素按某个字符分割以字符串形式存储。MYSQL中没有数组的原因是因为大多数人并不真正需要它。在关系型数据库中,通常使用关系模型,每个信息单元最好分配给单独的表行。例如,可能认为“我想要一个东西列表”,而是创建一个新表,将一个表中的行与另一个表中的行相关联;这样可以表示“M:N”关系。数据库可以索引这些行;而数组通常不会编入索引。

1. MySQL中以字符串的形式存储数组

MySQL中无数组类型,通常将数组元素按某个字符分割以字符串形式存储

1.1. 求数组中元素的个数

方法:按指定符号分割字符串,返回分割后的元素个数。要求的结果可以通过计算字符串中的分隔符号数量并加上1来得到,方法非常简单。

CREATE function Get_StrArrayLength 
(
@str varchar(1024), --要分割的字符串
@split varchar(10) --分隔符号
)
returns int
as
begin
declare @location int
declare @start int
declare @length int
set @str=ltrim(rtrim(@str))
set @location=charindex(@split,@str)
set @length=1
while @location<>0
begin
set @start=@location+1
set @location=charindex(@split,@str,@start)
set @length=@length+1
end
return @length
end

调用示例:

select  Get_StrArrayLength('78,1,2,3',',')

返回值:

4

1.2. 得到数组中指定位置的元素

方法:按指定符号分割字符串,返回分割后指定索引的第几个元素(注意索引从1开始),象数组一样方便

CREATE function Get_StrArrayStrOfIndex 
(
@str varchar(1024), --要分割的字符串
@split varchar(10), --分隔符号
@index int --取第几个元素
)
returns varchar(1024)
as
begin
declare @location int
declare @start int
declare @next int
declare @seed int
set @str=ltrim(rtrim(@str))
set @start=1
set @next=1
set @seed=len(@split)
set @location=charindex(@split,@str)
while @location<>0 and @index>@next
begin
set @start=@location+@seed
set @location=charindex(@split,@str,@start)
set @next=@next+1
end
if @location =0 select @location =len(@str)+1
--这儿存在两种情况:1、字符串不存在分隔符号 2、字符串中存在分隔符号,跳出while循环后,@location为0,那默认为字符串后边有一个分隔符号。
return substring(@str,@start,@location-@start)
end

调用示例:

select  Get_StrArrayStrOfIndex('8,9,4',',',2)

返回值:

9

1.3. 结合以上两个函数,遍历数组中的元素

方法:结合上边两个函数,象数组一样遍历字符串中的元素

declare @str varchar(50) 
set @str='1,2,3,4,5'
declare @next int
set @next=1
while @next<=Get_StrArrayLength(@str,',')
begin
print Get_StrArrayStrOfIndex(@str,',',@next)
set @next=@next+1
end

调用结果:

1
2
3
4
5

2.MySQL中存储数组(list)的示例

我在MySQL中有两个表。表Person具有以下列:

id | name | fruits

水果列可以包含空或像(‘apple’,’orange’,’banana’)或(‘strawberry’)等的字符串数组。第二个表是Table Fruit,有以下三列:

____________________________
fruit_name | color  | price
____________________________
apple      | red    | 2
____________________________
orange     | orange | 3
____________________________
...,...

那么我应该如何设计第一个表中的fruits列,以便它可以容纳从第二个表中的fruit_name列获取值的字符串数组?由于MySQL中没有数组数据类型,我该怎么办呢?

最佳答案:

正确的方法是使用多个表,并在查询中加入它们。

例如:

CREATE TABLE person (
`id` INT NOT NULL PRIMARY KEY,
`name` VARCHAR(50)
);
 
CREATE TABLE fruits (
`fruit_name` VARCHAR(20) NOT NULL PRIMARY KEY,
`color` VARCHAR(20),
`price` INT
);
 
CREATE TABLE person_fruit (
`person_id` INT NOT NULL,
`fruit_name` VARCHAR(20) NOT NULL,
PRIMARY KEY(`person_id`, `fruit_name`)
);

person_fruit表包含一个人与其相关联的每个水果的一行,并且有效地将人和水果表链接在一起。

1 | "banana"
1 | "apple"
1 | "orange"
2 | "straberry"
2 | "banana"
2 | "apple"

当你想检索一个人和他们的水果,你可以做这样的事情:

SELECT p.*, f.*
FROM person p
INNER JOIN person_fruit pf
ON p.id = pf.person_id
INNER JOIN fruits f
ON pf.fruit_name = f.fruit_name

说明一:

SQL中没有数组的原因是因为大多数人并不真正需要它。关系数据库(SQL就是这样)使用关系工作,并且大多数情况下,最好是为每个“信息位”分配一行表。例如,你可能认为“我想要一个东西列表”,而是创建一个新表,将一个表中的行与另一个表中的行相关联[1] 这样,您可以表示M:N关系。另一个优点是这些链接不会使包含链接项的行混乱。数据库可以索引这些行。数组通常不会编入索引。

如果您不需要关系数据库,则可以使用例如键值存储。

”的信息。 重写后的句子: 根据黄金法则,对于密钥和整个密钥事实,每个非关键属性都必须提供相应的信息。” 数组做得太多了。它有多个事实,它存储订单(与关系本身无关)。性能很差(见上文)。

想象一下,你有一张人桌,你有一张桌子,可以让人打电话。现在你可以让每个人都有他的电话列表。但每个人与许多其他事物有许多其他关系。这是否意味着我的人员表应该包含他连接的每一件事物的数组?不,这不是这个人本身的属性。

[1]:如果链接表只有两列(每个表的主键),这没关系!如果关系本身具有其他属性,则应在此表中将其表示为列。

说明二:

MySQL 5.7现在提供JSON数据类型。这种新的数据类型提供了一种存储复杂数据的便捷新方法:列表,字典等。

对象关系映射可能非常复杂,因为 Rrays 不能有效地映射到数据库。在MySQL中,历史上人们通常通过创建表来存储列表或数组,并将每个值作为记录添加。该表可能只有2或3列,或者可能包含更多列。如何存储此类数据实际上取决于数据的特征。

例如,列表是否包含静态或动态条目数?该列表是否会保持较小,或者预计会增长到数百万条记录?这张桌子上会有很多读物吗?很多写作?很多更新?在决定如何存储数据集合时,这些都是需要考虑的因素。

此外,密钥:价值数据存储/文件存储,如Cassandra,MongoDB,Redis等也提供了一个很好的解决方案。请注意数据实际存储的位置(如果存储在磁盘或内存中)。并非所有数据都需要位于同一数据库中。某些数据无法很好地映射到关系数据库,您可能有理由将其存储在其他位置,或者您可能希望使用内存中的键:值数据库作为存储在磁盘某处或作为临时存储的数据的热缓存像会话这样的东西。

以上就是mysql有没有数组的详细内容,更多请关注php中文网其它相关文章!

声明:本文转载于:亿速云,如有侵犯,请联系admin@php.cn删除