0

我继承了一个数据库,其中一个人表有一个名为 authorised_areas 的字段。前端允许用户从选择列表中选择多个条目(填充区域表的描述字段中的值),然后将 authorised_areas 的值设置为逗号分隔的列表。我正在将其迁移到 MySQL 数据库,当我使用它时,我想通过从 person 表中删除 authorised_areas 字段并创建一个多对多表 person_area 来提高数据库完整性-区域键。有几百个人记录,所以我想找到一种方法来有效地使用一些 MySQL 语句,而不是单独的插入或更新语句。

澄清一下,当前的结构类似于:

person
id    name    authorised_areas
1     Joe     room12, room153, 2nd floor office
2     Anna    room12, room17

area
id    description
1     room12
2     room17
3     room153
4     2nd floor office

...但我想要的是:

person
id    name
1     Joe
2     Anna

area
id    description
1     room12
2     room17
3     room153
4     2nd floor office

person_area
person_id     area_id
1             1
1             3
1             4
2             1
2             2

person 表中没有对 area id 的引用(并且列表中的某些文本值与 area 表中的描述不完全相同),因此这需要通过文本或模式匹配来完成。我最好只编写一些 php 代码来拆分字符串,找到匹配项并将适当的值插入到多对多表中吗?

如果我是第一个必须这样做的人,我会感到惊讶,但是谷歌搜索没有找到任何有用的东西(也许我没有使用适当的搜索词?)如果有人可以提供一些建议有效地做到这一点,我将非常感激。

4

1 回答 1

0

虽然可以做到这一点,但我建议作为一项临时工作,使用 php(或您最喜欢的脚本语言)脚本来执行多个插入可能会更快。

如果您必须在单个语句中执行此操作,则有一个整数表(0 到 9,与自身交叉连接以获得所需的最大范围)并将其与原始表连接,使用字符串函数获取第 X 个逗号以及每行的每个值。

可能的,我已经这样做了,但主要是为了表明有一个分隔字段不是一个好主意。敲出带有多个插入的脚本可能会更快。

您可以基于这样的 SELECT 插入(尽管这也会为每个人和相关人员提供一个空行,并且每人最多只能处理 1000 个授权区域)

SELECT z.id, z.name, x.an_authorised_area
FROM person z
LEFT OUTER JOIN (
SELECT DISTINCT a.id, SUBSTRING_INDEX( SUBSTRING_INDEX( authorised_areas, ",", b.ournumbers ) , ",", -1 ) AS an_authorised_area
FROM person a, (
SELECT hundreds.i *100 + tens.i *10 + units.i AS ournumbers
FROM integers AS hundreds
CROSS JOIN integers AS tens
CROSS JOIN integers AS units
)b
)x ON z.id = x.id
于 2012-10-19T11:47:22.927 回答