使用外键优化连接句子,并显示带空值的记录

时间:2009-11-06 22:46:54

标签: mysql join null foreign-keys

我有以下结构

SET SQL_MODE="NO_AUTO_VALUE_ON_ZERO";

CREATE TABLE IF NOT EXISTS `sis_param_tax` (
  `id` int(5) NOT NULL auto_increment,
  `description` varchar(50) NOT NULL,
  `code` varchar(5) NOT NULL,
  PRIMARY KEY  (`id`)
) ENGINE=InnoDB  DEFAULT CHARSET=latin1 AUTO_INCREMENT=7;

CREATE TABLE IF NOT EXISTS `sis_param_city` (
  `id` int(4) NOT NULL auto_increment,
  `name` varchar(100) NOT NULL,
  PRIMARY KEY  (`id`)
) ENGINE=InnoDB  DEFAULT CHARSET=latin1 AUTO_INCREMENT=3 ;

CREATE TABLE IF NOT EXISTS `sis_supplier` (
  `id` int(15) NOT NULL auto_increment,
  `name` varchar(200) NOT NULL,
  `address` varchar(200) default NULL,
  `phone` varchar(30) NOT NULL,
  `fk_city` int(11) default NULL,
  `fk_tax` int(11) default NULL,
  PRIMARY KEY  (`id`),
  KEY `fk_city` (`fk_city`),
  KEY `fk_tax` (`fk_tax`)
) ENGINE=InnoDB  DEFAULT CHARSET=latin1 AUTO_INCREMENT=2 ;

ALTER TABLE `sis_supplier`
  ADD CONSTRAINT `sis_supplier_ibfk_4` FOREIGN KEY (`fk_tax`) REFERENCES `sis_param_tax` (`id`) ON DELETE SET NULL ON UPDATE CASCADE,
  ADD CONSTRAINT `sis_supplier_ibfk_3` FOREIGN KEY (`fk_city`) REFERENCES `sis_param_city` (`id`) ON DELETE SET NULL ON UPDATE CASCADE;

我的问题是

1。这种结构允许我让一个供应商使用city和tax fields = null(如果用户没有设置这些值)。正确?

2. 如果我删除“X”城市,则供应商的城市=“X”的fk_city设置为null,与fk_tax相同。正确?

3。我想优化( IF可能 )以下的连接句子,这样我就可以向有fk_city和/或fk_city的供应商展示fk_tax = NULL

SELECT DISTINCT 
  sis_supplier.id,
  sis_supplier.name,
  sis_supplier.telefono,
  sis_supplier.address,
  sis_supplier.phone,
  sis_supplier.cuit,
  sis_param_city.name AS city,
  sis_param_tax.description AS tax,
  sis_supplier.fk_city,
  sis_supplier.fk_tax
FROM
  sis_supplier 
  LEFT OUTER JOIN sis_param_city
  ON
  sis_supplier.`fk_city` = sis_param_city.id
  LEFT OUTER JOIN `sis_param_tax`
  ON
  sis_supplier.`fk_tax` = `sis_param_tax`.`id`

提前多多感谢,

2 个答案:

答案 0 :(得分:2)

  1. 是的,优化很好。您显示的查询看起来很好。它怎么不适合你?


  2. 您是否使用EXPLAIN分析了查询?这可以帮助您判断何时查询未有效使用索引。事实上,建议阅读所有Chapter 7 Optimization

答案 1 :(得分:1)

如果要显示空值的记录,请使用 RIGHT或LEFT JOIN
取决于您的需求