如何从关系数据库中选择?

时间:2016-03-29 17:05:02

标签: php mysql database

我开始学习数据库是如何工作的,我总是将所有数据放在一个表中。我正在查看一个开源项目,我想创建一个接口,数据库结构太复杂,我无法理解。

我确信它有一个关系数据库结构(如果我已经正确学习)。这就是数据库结构的样子:

-- Table structure for table `databasechangelog`
--

CREATE TABLE IF NOT EXISTS `databasechangelog` (
  `ID` varchar(255) NOT NULL,
  `AUTHOR` varchar(255) NOT NULL,
  `FILENAME` varchar(255) NOT NULL,
  `DATEEXECUTED` datetime NOT NULL,
  `ORDEREXECUTED` int(11) NOT NULL,
  `EXECTYPE` varchar(10) NOT NULL,
  `MD5SUM` varchar(35) DEFAULT NULL,
  `DESCRIPTION` varchar(255) DEFAULT NULL,
  `COMMENTS` varchar(255) DEFAULT NULL,
  `TAG` varchar(255) DEFAULT NULL,
  `LIQUIBASE` varchar(20) DEFAULT NULL,
  `CONTEXTS` varchar(255) DEFAULT NULL,
  `LABELS` varchar(255) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

-- --------------------------------------------------------
-- Table structure for table `databasechangeloglock`
--

CREATE TABLE IF NOT EXISTS `databasechangeloglock` (
  `ID` int(11) NOT NULL,
  `LOCKED` bit(1) NOT NULL,
  `LOCKGRANTED` datetime DEFAULT NULL,
  `LOCKEDBY` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`ID`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

-- --------------------------------------------------------
-- Table structure for table `devices`
--

CREATE TABLE IF NOT EXISTS `devices` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(128) NOT NULL,
  `uniqueid` varchar(128) NOT NULL,
  `status` varchar(128) DEFAULT NULL,
  `lastupdate` timestamp NULL DEFAULT NULL,
  `positionid` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `uk_device_uniqueid` (`uniqueid`)
) ENGINE=InnoDB  DEFAULT CHARSET=latin1 AUTO_INCREMENT=2 ;

-- --------------------------------------------------------
-- Table structure for table `positions`
--

CREATE TABLE IF NOT EXISTS `positions` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `protocol` varchar(128) DEFAULT NULL,
  `deviceid` int(11) NOT NULL,
  `servertime` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  `devicetime` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
  `fixtime` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
  `valid` bit(1) NOT NULL,
  `latitude` double NOT NULL,
  `longitude` double NOT NULL,
  `altitude` float NOT NULL,
  `speed` float NOT NULL,
  `course` float NOT NULL,
  `address` varchar(512) DEFAULT NULL,
  `attributes` varchar(4096) NOT NULL,
  PRIMARY KEY (`id`),
  KEY `position_deviceid_fixtime` (`deviceid`,`fixtime`)
) ENGINE=InnoDB  DEFAULT CHARSET=latin1 AUTO_INCREMENT=145 ;

-- --------------------------------------------------------
-- Table structure for table `server`
--

CREATE TABLE IF NOT EXISTS `server` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `registration` bit(1) NOT NULL DEFAULT b'1',
  `latitude` double NOT NULL DEFAULT '0',
  `longitude` double NOT NULL DEFAULT '0',
  `zoom` int(11) NOT NULL DEFAULT '0',
  `map` varchar(128) DEFAULT NULL,
  `language` varchar(128) DEFAULT NULL,
  `distanceunit` varchar(128) DEFAULT NULL,
  `speedunit` varchar(128) DEFAULT NULL,
  `bingkey` varchar(128) DEFAULT NULL,
  `mapurl` varchar(128) DEFAULT NULL,
  `readonly` bit(1) NOT NULL DEFAULT b'0',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB  DEFAULT CHARSET=latin1 AUTO_INCREMENT=2 ;

-- --------------------------------------------------------
-- Table structure for table `users`
--

CREATE TABLE IF NOT EXISTS `users` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(128) NOT NULL,
  `email` varchar(128) NOT NULL,
  `hashedpassword` varchar(128) NOT NULL,
  `salt` varchar(128) NOT NULL,
  `readonly` bit(1) NOT NULL DEFAULT b'0',
  `admin` bit(1) NOT NULL DEFAULT b'0',
  `map` varchar(128) NOT NULL DEFAULT 'osm',
  `language` varchar(128) NOT NULL DEFAULT 'en',
  `distanceunit` varchar(128) NOT NULL DEFAULT 'km',
  `speedunit` varchar(128) NOT NULL DEFAULT 'kmh',
  `latitude` double NOT NULL DEFAULT '0',
  `longitude` double NOT NULL DEFAULT '0',
  `zoom` int(11) NOT NULL DEFAULT '0',
  PRIMARY KEY (`id`),
  UNIQUE KEY `uk_user_email` (`email`)
) ENGINE=InnoDB  DEFAULT CHARSET=latin1 AUTO_INCREMENT=3 ;

-- --------------------------------------------------------
-- Table structure for table `user_device`
--

CREATE TABLE IF NOT EXISTS `user_device` (
  `userid` int(11) NOT NULL,
  `deviceid` int(11) NOT NULL,
  KEY `fk_user_device_deviceid` (`deviceid`),
  KEY `user_device_user_id` (`userid`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

--
-- Constraints for dumped tables
--

--
-- Constraints for table `positions`
--
ALTER TABLE `positions`
  ADD CONSTRAINT `fk_position_deviceid` FOREIGN KEY (`deviceid`) REFERENCES `devices` (`id`) ON DELETE CASCADE;

--
-- Constraints for table `user_device`
--
ALTER TABLE `user_device`
  ADD CONSTRAINT `fk_user_device_deviceid` FOREIGN KEY (`deviceid`) REFERENCES `devices` (`id`) ON DELETE CASCADE,
  ADD CONSTRAINT `fk_user_device_userid` FOREIGN KEY (`userid`) REFERENCES `users` (`id`) ON DELETE CASCADE;

当用户注册时,它会在“users”表中添加一个条目,并且用户会获得一个id。

然后,当用户添加设备时,user_device表如下所示:

enter image description here

设备表如下所示:

enter image description here

这是一款GPS跟踪软件,因此每个设备都会在“位置”表中发布它的位置,如下所示:

enter image description here

因此,如果用户登录,如何查询位置表并从该用户的所有设备获取所有信息?我假设我需要加入表格,但我不知道该怎么做。任何帮助将不胜感激。

2 个答案:

答案 0 :(得分:2)

让我们逐步建立它。首先,您想要的实际数据是什么?

  

查询职位表

好的,从那开始:

SELECT
  *
FROM
  positions

现在您想如何进一步过滤该数据?

  

来自该用户的所有设备

好的,我们需要将此表(positions)通过设备与用户联系起来。所以最终我们需要这样的WHERE条款:

WHERE
  userid = ?

但是positions没有userid,所以让我们一起来加入一些表,直到我们有一个表。 positions deviceid,因此我们可以加入:

SELECT
  *
FROM
  positions
  INNER JOIN devices
    ON positions.deviceid = devices.id

但我们仍然没有useriddevices本身并没有引用任何内容来进一步帮助我们。但是, 引用devicesuser_device的表格。让我们加入:

SELECT
  *
FROM
  positions
  INNER JOIN devices
    ON positions.deviceid = devices.id
  INNER JOIN user_device
    ON devices.id = user_device.deviceid

您会发现我们现在获得了大量数据。但是,您还会看到我们现在正在获取userid列,因此我们最终可以添加WHERE子句:

SELECT
  *
FROM
  positions
  INNER JOIN devices
    ON positions.deviceid = devices.id
  INNER JOIN user_device
    ON devices.id = user_device.deviceid
WHERE
  userid = ?

此时,我们应该从与positions相关的任何device中获取所有唯一user。您可以通过将position替换为SELECT *来获取 SELECT positions.*数据,或者您可以明确定义要从哪些表中选择哪些列。

答案 1 :(得分:0)

从您的笔记中可以看出,您知道用户何时登录他所拥有的设备。如果这是正确的,您不应该需要加入。只需在position.deviceid =登录设备的位置表上进行选择。