简体   繁体   English

MySQL联接表一对多关系

[英]MySQL joining tables one-to-many relationship

I am trying to achieve something in MySQL but even with all the answers here or on other sites, I still cannot accomplish the goal. 我正在尝试在MySQL中实现某些目标,但是即使在这里或其他站点获得了所有答案,我仍然无法实现目标。

I have two tables, in one-to-many relationship. 我有两个表,一对多关系。

TABLE Files
COLUMNS id, title, description, uploaded, size, extension, etc.

TABLE Files_Meta
COLUMNS id, parent_id, key, value

Obviously each file has multiple meta data represented as many rows in the Files_Meta table. 显然,每个文件都具有表示为Files_Meta表中许多行的多个元数据。 For example File1 has meta Author, Place, Time, Tags, Camera -- if it's a photo. 例如, File1具有元作者,位置,时间,标签,相机-如果是照片。

I'm trying to select all rows from Files table including meta data. 我正在尝试从文件表中选择所有行,包括元数据。

Standard result 标准结果

stdClass Object
(
[id] => 10
[title] => Hello world
[size] => 745198
[extension] => jpg
[user_id] => 0
[category_id] => 0
[date_uploaded] => 2012-06-08 13:37:55
[description] => 
[downloaded] => 0
[viewed] => 8
)

stdClass Object
(
[id] => 90
[parent_id] => 10
[key] => place
[value] => New York
)

What I want 我想要的是

stdClass Object
(
[id] => 10
[title] => Hello world
[size] => 745198
[extension] => jpg
[user_id] => 0
[category_id] => 0
[date_uploaded] => 2012-06-08 13:37:55
[description] => 
[downloaded] => 0
[viewed] => 8
[meta] => Array (
    place => New York
    author => John Doe
    time => March 2001
    camera => Canon EOS
    etc.
    )
)

Is it possible to achieve this in MySQL? 有可能在MySQL中实现吗? Doesn't have to look like this, without that array. 如果没有该数组,则不必看起来像这样。

stdClass Object
(
[id] => 10
.
.
[place] => New York
[author] => John Doe
[time] => March 2001
[camera] => Canon EOS
)

Thanks in advance for replies or tips. 在此先感谢您的答复或提示。

Doing this in a single query could be as follows: 可以在单个查询中执行以下操作:

SELECT * FROM Files INNER JOIN Files_Meta ON Files.id = Files_Meta.parent_id

Per the comments, you will need PHP to create the structure you desire as MySQL only returns results in a flat fashion. 根据注释,您将需要PHP创建所需的结构,因为MySQL仅以固定方式返回结果。

I strongly advise writing your code to do this in a single query or with 2 queries - one for all Files and another for all Files_Meta . 我强烈建议编写您的代码以通过单个查询或两个查询来执行此操作-一个查询所有Files ,另一个查询所有Files_Meta Then stitch the data together with PHP. 然后使用PHP将数据缝合在一起。 Otherwise, you may create an N+1 Problem . 否则,您可能会创建N + 1问题

As an aside, I recommend changing parent_id to file_id . parent_id file_id ,我建议将parent_id更改为file_id parent_id typical denotes of a self-referential key. parent_id通常表示自引用密钥。 Whereas file_id would denote a foreign key to the File table. file_id将表示File表的外键。

As you also tagged PHP - I would recommend you to use an PHP ORM Framework like Doctrine or Propel which would give you a structure like that (which is very abstract): 正如您还标记了PHP一样-我建议您使用像Doctrine或Propel这样的PHP ORM框架,它将为您提供这样的结构(非常抽象):

class File {

/* members */

var id // int
var title // string
var description // string
var uploaded // boolean
var size // int
var extension // string
var metadata // array (Collection of FileMeta)

/* getters setters for each member */
...

}

class FileMeta {

var id // int
var fileId // the id to the File object
var file // the fileobject itself
var key // string
var value // string

}

The only thing you have to do is define your structure (maybe exported from your database) and thats it. 您唯一要做的就是定义您的结构(也许从数据库中导出),然后就可以了。

I hope this is not too far away from what you searched. 我希望这与您搜索的内容相距不远。

Sounds like you are looking for a join. 听起来您正在寻找联接。 This would be great if there was only one meta per file. 如果每个文件只有一个meta,那就太好了。 More than one meta per file would result in numerous resulting rows with only the meta data being different. 每个文件一个以上的元数据将导致大量结果行,而只有元数据不同。 However, I assume since you are displaying photo data that this is not true and would only get one meta per file so I would suggest this SQL: 但是,我假设由于您正在显示照片数据,所以这不是正确的,并且每个文件只能得到一个元数据,因此我建议使用以下SQL:

SELECT 
    Files.*,
    Files_Meta.place, Files_Meta.author, Files_Meta.time, Files_Meta.camera, ..etc 
FROM 
    Files
JOIN Files_Meta ON Files_Meta.parent_id = Files.id

This will give you a flat representation consisting of the data you were fetching in two separate queries and then combining via PHP. 这将为您提供一个扁平化的表示形式,其中包含您在两个单独的查询中获取的数据,然后通过PHP进行合并。 Relying on your database is always better than having to manually stitch stuff together when possible and as long as the parent_id and the id in files are indexed the query should be lightning fast. 依靠数据库总是比在可能的情况下必须手动缝合东西要好,只要索引了文件中的parent_id和id,查询就应该很快。

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

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