我想从Openstack MySQL数据库中获取一些信息,但是我的查询能力有限,我认为我需要对来自两个不同数据库的三个表进行联接。
表的结构如下:
mysql> describe neutron.ipallocations;
+------------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+------------+-------------+------+-----+---------+-------+
| port_id | varchar(36) | YES | MUL | NULL | |
| ip_address | varchar(64) | NO | PRI | NULL | |
| subnet_id | varchar(36) | NO | PRI | NULL | |
| network_id | varchar(36) | NO | PRI | NULL | |
+------------+-------------+------+-----+---------+-------+
mysql> describe neutron.ports;
+----------------+--------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+----------------+--------------+------+-----+---------+-------+
| tenant_id | varchar(255) | YES | | NULL | |
| id | varchar(36) | NO | PRI | NULL | |
| name | varchar(255) | YES | | NULL | |
| network_id | varchar(36) | NO | MUL | NULL | |
| mac_address | varchar(32) | NO | | NULL | |
| admin_state_up | tinyint(1) | NO | | NULL | |
| status | varchar(16) | NO | | NULL | |
| device_id | varchar(255) | NO | | NULL | |
| device_owner | varchar(255) | NO | | NULL | |
+----------------+--------------+------+-----+---------+-------+
mysql> describe nova.instances;
+----------------------+-----------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+----------------------+-----------------------+------+-----+---------+----------------+
| uuid | varchar(36) | YES | UNI | NULL | |
| hostname | varchar(255) | YES | | NULL | |
| deleted | int(11) | YES | | NULL | |
+----------------------+-----------------------+------+-----+---------+----------------+
由于nova表架构很大,因此我已将其截短以仅包含我需要的字段。
我想做的是将所有实例的主机名(nova.instance表)与它们的ip_address(neutron.ipallocation表)相关联。实例在已删除字段中应为0,以表明它们是活动的。
但是,两者之间没有直接映射。链接表是neutron.ports。
在neutron.ports中,device_id与实例uuid以及neutron.ipaccolcation port_id是一对一关系
因此,我尝试了以下方法:
SELECT a.ip_address,c.hostname
FROM neutron.ipallocations a, neutron.ports b,nova.instances c
WHERE c.deleted='0'
AND b.device_id = c.uuid
AND a.port_id = b.device_id;
这不会返回任何结果,因此可能出了点问题。
也尝试使用LEFT和INNER JOINS
SELECT ni.hostname, i.ip_address
FROM nova.instances ni
LEFT JOIN neutron.ports p
INNER JOIN neutron.ipallocations i
ON i.port_id = p.device_id
ON ni.uuid = p.device_id WHERE ni.deleted ='0';
该查询返回主机名,但ip_address列为NULL,因此我认为我丢失了一些内容。
我真的不知道我是否需要为此使用联接,或者可以以更简单的方式完成它。
如果有人对此有任何指示或解决方案,我将不胜感激。
抱歉让您感到困惑,下面是一些示例数据:
select * from neutron.ipallocations;
+--------------------------------------+--------------+--------------------------------------+--------------------------------------+
| port_id | ip_address | subnet_id | network_id |
+--------------------------------------+--------------+--------------------------------------+--------------------------------------+
| 13433d6d-bf47-476b-a841-324aba4a902d | 192.168.14.5 | b024436e-7c69-42ff-b504-219ce9979792 | 96a8fd64-8a94-476d-b9c8-c28055d39041 |
| 5b66e69f-829d-419e-8116-889e0ad36c35 | 192.168.14.7 | b024436e-7c69-42ff-b504-219ce9979792 | 96a8fd64-8a94-476d-b9c8-c28055d39041 |
| 8e32216f-11db-437f-981d-cfe03e90baed | 192.168.14.4 | 07e516af-1162-4bfc-946b-fdc259b013c9 | bdfdb6d6-c0bc-4bdb-896e-6e5919d232c2 |
| 92a45ed8-a472-4845-841f-604259c07ab2 | 192.168.14.6 | b024436e-7c69-42ff-b504-219ce9979792 | 96a8fd64-8a94-476d-b9c8-c28055d39041 |
+--------------------------------------+--------------+--------------------------------------+--------------------------------------+
该表中的port_id映射到neutron.ports中的id字段:
select * from neutron.ports;
+----------------------------------+--------------------------------------+------+--------------------------------------+-------------------+----------------+--------+-------------------------------------------------------------------------------+--------------+
| tenant_id | id | name | network_id | mac_address | admin_state_up | status | device_id | device_owner |
+----------------------------------+--------------------------------------+------+--------------------------------------+-------------------+----------------+--------+-------------------------------------------------------------------------------+--------------+
| 9a111d6e4dd0440fab4cc7b610efd2bf | 13433d6d-bf47-476b-a841-324aba4a902d | | 96a8fd64-8a94-476d-b9c8-c28055d39041 | fa:16:3e:6b:ed:5d | 1 | ACTIVE | dhcpc7e0c2c5-8a56-5b48-a120-03c05bff04a5-96a8fd64-8a94-476d-b9c8-c28055d39041 | network:dhcp |
| 9a111d6e4dd0440fab4cc7b610efd2bf | 5b66e69f-829d-419e-8116-889e0ad36c35 | | 96a8fd64-8a94-476d-b9c8-c28055d39041 | fa:16:3e:b9:4d:2e | 1 | ACTIVE | 578485e5-9f5f-405c-a09a-24f89b81a43c | compute:nova |
| 9a111d6e4dd0440fab4cc7b610efd2bf | 8e32216f-11db-437f-981d-cfe03e90baed | | bdfdb6d6-c0bc-4bdb-896e-6e5919d232c2 | fa:16:3e:55:af:d5 | 1 | ACTIVE | dhcpc7e0c2c5-8a56-5b48-a120-03c05bff04a5-bdfdb6d6-c0bc-4bdb-896e-6e5919d232c2 | network:dhcp |
| 9a111d6e4dd0440fab4cc7b610efd2bf | 92a45ed8-a472-4845-841f-604259c07ab2 | | 96a8fd64-8a94-476d-b9c8-c28055d39041 | fa:16:3e:06:ad:13 | 1 | ACTIVE | 221a44fe-23e6-4003-8170-dafedeeaf333 | compute:nova |
+----------------------------------+--------------------------------------+------+--------------------------------------+-------------------+----------------+--------+-------------------------------------------------------------------------------+--------------+
并且neutron.ports中的device_id映射到nova.instances中的uuid:
mysql> select uuid,hostname,deleted from nova.instances where deleted ='0';
+--------------------------------------+--------------------------------+---------+
| uuid | hostname | deleted |
+--------------------------------------+--------------------------------+---------+
| 221a44fe-23e6-4003-8170-dafedeeaf333 | host1.test.net | 0 |
| 578485e5-9f5f-405c-a09a-24f89b81a43c | host2.test.net | 0 |
+--------------------------------------+--------------------------------+---------+
最佳答案
布伦特
我们正在回答这个问题的问题是,我们不了解nova.instances中的哪些数据与neutron.ports数据相匹配。从您的尝试看来,您希望nova.instances.uuid
与neutron.ports.device_id
匹配。在这种情况下,您的第一个查询应该可以工作。
您能否提供一些样本数据和预期的输出?我认为这可以消除我们的困惑。
编辑
关于您的首选语法问题,我怀疑Barmar会屈从于where子句所限制的笛卡尔联接。请考虑以下查询:
SELECT ip.ip_address
,i.hostname
FROM neutron.ipallocations ip
JOIN neutron.ports p ON ip.port_id = p.id
JOIN nova.instances i ON p.device_id = i.uuid
WHERE i.deleted = '0';
为了清楚起见,优化器应该为两个查询选择相同的执行路径,但是使用
on
子句会使查询更具可读性。我也更改了别名;我个人更喜欢别名有意义的名字。