将 SQL 数据库中的约束提取到 PHP 中的 JSON
Posted
技术标签:
【中文标题】将 SQL 数据库中的约束提取到 PHP 中的 JSON【英文标题】:Fetching constraints in SQL database to JSON in PHP 【发布时间】:2019-08-07 16:30:54 【问题描述】:假设我有以下汽车制造商和相应汽车的数据库结构:
制造商:
----------------------------------
| manufacturer | founded_in | id |
|--------------|------------|----|
| Daimler AG | 1927 | 1 |
| Volkswagen AG| 1937 | 2 |
----------------------------------
汽车:
-------------------------------------
| car | built_in | manufacturer |
|---------|----------|---------------
| C Class | 1993 | 1 |
| E Class | 1993 | 1 |
| Golf | 1974 | 2 |
-------------------------------------
manufacturers
的id
列是主键,cars
的manufacturer
列有对应的外键约束。
我想使用 php json_encode
生成以下 JSON 输出:
"manufacturers":
"Daimler AG":
"founded in": "1927",
"cars": [
"C Class",
"E Class"
]
,
"Volkswagen AG":
"founded in": "1937",
"cars": [
"Golf"
]
为了让制造商和他们的founded_in
我只是执行:
SELECT manufacturer, founded_in FROM manufacturers
并将它们提取到一个数组中。但是,在进行第二次查询后,如何正确分配汽车?
【问题讨论】:
我猜你可以通过内部连接来做到这一点。 怎么样?我需要一次将多辆汽车分配给一个制造商。 【参考方案1】:您还可以使用对象关系映射器,例如 Respect/Relational
您可以简单地调用:
use Respect\Relational\Mapper;
$mapper = new Mapper(new PDO($db_string, $db_user, $db_pass));
$results = $mapper->manufacturers->cars->fetchAll();
$json = json_encode($results);
把繁重的工作交给 API。
【讨论】:
【参考方案2】:如果您使用的是 mysql 5.7 或更高版本,则可以使用 JSON 聚合函数直接从 SQL 查询生成您期望的输出。我希望这会比在两者之间使用 php 更有效。
首先,考虑以下聚合查询,JOIN
s 两个表并为每个制造商创建一个 JSON 对象,并在子数组中包含相关汽车名称的列表:
SELECT JSON_OBJECT('founded in', m.founded_in, 'cars', JSON_ARRAYAGG(c.car)) js
FROM manufacturers m
INNER JOIN cars c ON c.manufacturer = m.id
GROUP BY m.id, m.founded_in;
这会返回:
| js |
| ---------------------------------------------------- |
| "cars": ["C Class", "E Class"], "founded in": 1927 |
| "cars": ["Golf"], "founded in": 1937 |
要产生预期的输出,我们可以将其转换为子查询并添加另一个级别的聚合:
SELECT JSON_OBJECT('manufacturers', JSON_OBJECTAGG(manufacturer, js)) myjson
FROM (
SELECT
m.id,
m.manufacturer,
JSON_OBJECT('founded in', m.founded_in, 'cars', JSON_ARRAYAGG(c.car)) js
FROM manufacturers m
INNER JOIN cars c ON c.manufacturer = m.id
GROUP BY m.id, m.manufacturer, m.founded_in
) x
这会产生:
| myjson |
| ------------------------------------------------------------------------------------------------------------------------------------------------ |
| "manufacturers": "Daimler AG": "cars": ["C Class", "E Class"], "founded in": 1927, "Volkswagen AG": "cars": ["Golf"], "founded in": 1937 |
Demo on DB Fiddle。
【讨论】:
【参考方案3】:可以先查询所有数据
SELECT m.manufacturer, m.founded_in
FROM manufacturers AS m
JOIN cars AS c ON c.manufacturer_id = m.id
然后将其转换为你在 php 中的结构
$manufacturers = [];
foreach ($rows as $row)
if (!array_key_exists($row['manufacturer'], $manufacturers))
$manufacturers[$row['manufacturer']] = array(
'founded_in' => $row['founded_in'],
'cars' => array());
array_push($manufactureres[$row['manufacturer']]['cars'], $row['car']);
当然,在 php 中有一种更实用的方法可以做到这一点,但你应该可以这样做......
【讨论】:
那么您是否建议我应该加入两个表,这些表中的制造商列中的所有行都已填充,即使我只有两个?这算是好的做法吗? 嗯,这取决于你有多少数据。您也可以有两个单独的查询,并填充相同的结构。 作为一种习惯,你可以说,让数据库来处理这一切,因为它是为这样的东西而生的。如果成本太高,您可以将虚假值填充到测试数据库中并运行基准测试。以上是关于将 SQL 数据库中的约束提取到 PHP 中的 JSON的主要内容,如果未能解决你的问题,请参考以下文章