近期刚学mysql很多东西都没太了解(不知道有没有什么高级的指令)原本是用yml存储数据的
数据示例如下:
复制代码一个列表里有N个GuildName(数量未知,这不废话吗)
members里也有N个玩家
但我现在要转用Mysql来存储该这么存才合理呢?
members里的玩家是有归属性的,
我要实现能够用 <GuildName>来查找到他包含的成员
数据示例如下:
- List:
- <GuildName>:
- members:
- - 'xxx'
- - 'xxx'
- <GuildName>:
- members:
- - 'xxx'
- - 'xxx'
members里也有N个玩家
但我现在要转用Mysql来存储该这么存才合理呢?
members里的玩家是有归属性的,
我要实现能够用 <GuildName>来查找到他包含的成员
=============
GuildName | table
=============
guildname1 | table1
guildname2 | table2
xxxx
=============
总不能给每个guildname都分配一个表吧
本帖最后由 凌语丶 于 2023-1-31 12:12 编辑
az
add column GuildName TEXT
select * from table_name where GuildName = ?
az
add column GuildName TEXT
select * from table_name where GuildName = ?
凌语丶 发表于 2023-1-31 12:11
az
add column GuildName TEXT
select * from table_name where GuildName = ?
额....
我是要考 guildname查玩家,不是查guildname
guildname里有个键叫members
members里存玩家列表
但我不知道怎么存才好
本帖最后由 ARSpark 于 2023-1-31 13:04 编辑
解释一下楼上的意思:MySQL 不是 Map,它是按行记录的,所以存储方式类似:
复制代码
翻译到 SQL 语句是
复制代码
(数据类型根据实际情况选择,INDEX 让查找快点)
查询一个 guildName 的数据时(以 Guild01 为例)
复制代码
MySQL 会返回多条记录,如果是 JDBC 的话用 ResultSet 一行行读就可以
写的时候也是一个一个写(还是以 Guild01 为例):
复制代码
大致就是这样的意思
当然另一个方案是把 members 收集到一个 List 然后序列化(转为字符串),并用 TEXT 形式存储,但需要额外的转换步骤,比较繁琐
解释一下楼上的意思:MySQL 不是 Map,它是按行记录的,所以存储方式类似:
- | GuildName | MemberID |
- ------------------------
- | Guild01 | Member01 |
- | Guild01 | Member02 |
- | Guild01 | Member03 |
- ...
- | Guild02 | Member01 |
- | Guild02 | Member03 |
- | Guild02 | Member05 |
翻译到 SQL 语句是
- CREATE TABLE table_name (
- guildName VARCHAR(255) INDEX NOT NULL,
- memberName VARCHAR(255) NOT NULL
- );
(数据类型根据实际情况选择,INDEX 让查找快点)
查询一个 guildName 的数据时(以 Guild01 为例)
- SELECT memberName FROM table_name WHERE guildName="Guild01";
MySQL 会返回多条记录,如果是 JDBC 的话用 ResultSet 一行行读就可以
写的时候也是一个一个写(还是以 Guild01 为例):
- INSERT INTO table_name (guildName, memberName) VALUES ("Guild01", "Member01");
- INSERT INTO table_name (guildName, memberName) VALUES ("Guild01", "Member02");
- INSERT INTO table_name (guildName, memberName) VALUES ("Guild01", "Member03");
大致就是这样的意思
当然另一个方案是把 members 收集到一个 List 然后序列化(转为字符串),并用 TEXT 形式存储,但需要额外的转换步骤,比较繁琐
本帖最后由 LING_Y_ 于 2023-1-31 13:35 编辑
上面说了
members只是我代指的一个词,他是一个列表,里面存储着 Guildname所属的玩家,
mysql里没有list和Text[]的数据类型没法存
所以我想知道有什么办法能够做到我
select members from whre guildName = ?
可以返回一个玩家列表
但吧list弄成字符串可能会有些繁琐而且就怕出什么叉子,
有什么办法能转成json形式的吗
ARSpark 发表于 2023-1-31 12:50
解释一下楼上的意思:MySQL 不是 Map,它是按行记录的,所以存储方式类似:
上面说了
一个列表里有N个GuildName(数量未知,这不废话吗)
members里也有N个玩家
但我现在要转用Mysql来存储该这么存才合理呢?
members里的玩家是有归属性的,
我要实现能够用 <GuildName>来查找到他包含的成员
members只是我代指的一个词,他是一个列表,里面存储着 Guildname所属的玩家,
mysql里没有list和Text[]的数据类型没法存
所以我想知道有什么办法能够做到我
select members from whre guildName = ?
可以返回一个玩家列表
但吧list弄成字符串可能会有些繁琐而且就怕出什么叉子,
有什么办法能转成json形式的吗
本帖最后由 结冰的离季 于 2023-1-31 14:12 编辑
你可以学一下数据库的三大范式
从你的问题可以抽象出3张表
玩家表(id,Name,...其他属性)
工会表(id,name,...其他属性)
玩家公会表(玩家id,工会id) 此比表属于关系集
玩家与工会之间并没共同的属性,所以是独立的
关系集是实体集之间的关系
无论是获取玩家所属的工会还是获取某个工会的所有玩家都可以从关系集中提取
缺点就是查询的语句较复杂,需要连接
你可以学一下数据库的三大范式
从你的问题可以抽象出3张表
玩家表(id,Name,...其他属性)
工会表(id,name,...其他属性)
玩家公会表(玩家id,工会id) 此比表属于关系集
玩家与工会之间并没共同的属性,所以是独立的
关系集是实体集之间的关系
无论是获取玩家所属的工会还是获取某个工会的所有玩家都可以从关系集中提取
缺点就是查询的语句较复杂,需要连接
起两张表, 一张存公会的详细信息, 一张存玩家的详细信息:
table_guild:
id|name|member_count|whatever
table_member:
uuid|username|belong(NULLABLE)|whatever
查的的时候查两次, 第一次根据组名找出组id, 第二次根据组id找出组里的所有玩家.
这个方法应该非常容易想到, 但是你可能不大理解为什么这么做, 难道没有只查询一次的办法么?
当然有, 你直接把玩家所属公会的信息直接写进玩家数据本身上面:
table_member:
uuid|username|belong(NULLABLE)|groupname|whatever
但是这样你会发现, 如果这个公会要改个名, 或者什么乱七八糟的, 所有在公会里的玩家都要被更新一次, 太蠢了.
把这两者分离存储, 是很多网站和程序经过实践得到的最佳答案, 包括论坛本身所用的discuz, 也不会将用户所属的用户组信息直接写进用户表本身, 而是只留一个组id在用户表里, 这样数据表的结构干净简明, 也方便维护.
MySQL这样的数据库没有办法存储你那样结构复杂的数据, 你需要转变一下你的思想, 不要用存json什么的思想去套用在mysql上面, 行不通的.
table_guild:
id|name|member_count|whatever
table_member:
uuid|username|belong(NULLABLE)|whatever
查的的时候查两次, 第一次根据组名找出组id, 第二次根据组id找出组里的所有玩家.
这个方法应该非常容易想到, 但是你可能不大理解为什么这么做, 难道没有只查询一次的办法么?
当然有, 你直接把玩家所属公会的信息直接写进玩家数据本身上面:
table_member:
uuid|username|belong(NULLABLE)|groupname|whatever
但是这样你会发现, 如果这个公会要改个名, 或者什么乱七八糟的, 所有在公会里的玩家都要被更新一次, 太蠢了.
把这两者分离存储, 是很多网站和程序经过实践得到的最佳答案, 包括论坛本身所用的discuz, 也不会将用户所属的用户组信息直接写进用户表本身, 而是只留一个组id在用户表里, 这样数据表的结构干净简明, 也方便维护.
MySQL这样的数据库没有办法存储你那样结构复杂的数据, 你需要转变一下你的思想, 不要用存json什么的思想去套用在mysql上面, 行不通的.
本帖最后由 双螺旋 于 2023-1-31 19:13 编辑
json序列化
表头:Guild(varchar 255) Members List<String> (varchar 10000)
Members那个List序列化完扔进去
json序列化
表头:Guild(varchar 255) Members List<String> (varchar 10000)
Members那个List序列化完扔进去
本帖最后由 ARSpark 于 2023-1-31 20:15 编辑
你的思路还是把数据库当成了一个 Map,认为需要这样的一个存储方式:
复制代码然后,当然,List<String> 不能在不序列化的情况下存入 DB,所以你想要把它转换到 JSON 之类的方法:
复制代码问题在于,关系型数据库它不是这样组织数据的,它存储的是记录,而不仅仅是键值对,如果用上面回答中的方法存储数据,那么语句
复制代码
返回的结果就是一组记录(而不是一条)
你可以认为 MySQL 是这么工作的(当然实际实现并非如此),写成伪代码:
复制代码
如果一定要代码才能说清楚,以下是对应的 Java/JDBC 代码(只提供方法实现,略去了创建数据表和错误处理等工作,亦不是最好性能,仅供理解):
当然了,这种数据组织方式只记录了玩家和公会之间的关联关系,Zapic 的回答也告诉你,guildName 和 member 都应该是 ID(唯一标识符),并如果有需要存储公会和玩家的详细信息,应另开表格处理(回答中其实是把所属公会和玩家的其它信息合并了,减少一张表,但就题论题而言以上方法是足够了,当然如果玩家可以属于不止一个公会,事情就会变得复杂,但上面这张表还是可以处理)
LING_Y_ 发表于 2023-1-31 13:33
上面说了
members只是我代指的一个词,他是一个列表,里面存储着 Guildname所属的玩家,
mysql里没有list ...
你的思路还是把数据库当成了一个 Map,认为需要这样的一个存储方式:
- List<String> members = GUILDDATA.get("YourGuildNameHere");
- Map<String, String> simulateDB = virtualDatabase();
- String membersSerialized = simulateDB.get("YourGuildNameHere");
- List<String> members = somehowDeserialize(membersSerialized);
- SELECT memberName FROM tableName WHERE guildName="YourNameHere"
返回的结果就是一组记录(而不是一条)
你可以认为 MySQL 是这么工作的(当然实际实现并非如此),写成伪代码:
- // SELECT memberName FROM tableName WHERE guildName=Example
- result = []
- for line of allRecords:
- if line.guildName == Example
- result.add(line.memberName)
- return result
如果一定要代码才能说清楚,以下是对应的 Java/JDBC 代码(只提供方法实现,略去了创建数据表和错误处理等工作,亦不是最好性能,仅供理解):
当然了,这种数据组织方式只记录了玩家和公会之间的关联关系,Zapic 的回答也告诉你,guildName 和 member 都应该是 ID(唯一标识符),并如果有需要存储公会和玩家的详细信息,应另开表格处理(回答中其实是把所属公会和玩家的其它信息合并了,减少一张表,但就题论题而言以上方法是足够了,当然如果玩家可以属于不止一个公会,事情就会变得复杂,但上面这张表还是可以处理)
本帖最后由 美年达呀 于 2023-2-7 18:35 编辑
两张表三张表都能实现,做一个多表查询就行了1.定义Gui表 表中字段填写你需要的属性即可
2.定义Member表 表中字段填写玩家属性即可
俩张表需要Member表中填写Gui表的id属性(不建议那么操作)
三张表就定义Gui_info表 表中字段填写 id 、gui表的id、member表的id
查就查gui_info表
举个例子:
需求:该工会下的所有成员名字
复制代码
两张表三张表都能实现,做一个多表查询就行了1.定义Gui表 表中字段填写你需要的属性即可
2.定义Member表 表中字段填写玩家属性即可
俩张表需要Member表中填写Gui表的id属性(不建议那么操作)
三张表就定义Gui_info表 表中字段填写 id 、gui表的id、member表的id
查就查gui_info表
举个例子:
需求:该工会下的所有成员名字
- select member.name from gui_info,member where gui_info.member_id = member.id