我想从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 |
+--------------------------------------+--------------------------------+---------+
答案 0 :(得分: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
子句可使查询更具可读性。我也改变了别名;我个人更喜欢名字有意义的别名。