So i'm trying to create a library database and was wondering if something i'm trying to achieve is possible through the use of triggers or similar.
I have this table called "category" which contains the different categories that you can borrow, like books or dvds.
And depending on what product category you lend from, you have different times allowed, like books you can borrow for 3 weeks but dvds are only allowed 3 days.
+--------------+---------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+--------------+---------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| name | varchar(100) | NO | | NULL | |
| time_allowed | time | NO | | NULL | |
| days_allowed | varchar(400) | NO | | NULL | |
+--------------+---------------+------+-----+---------+----------------+
And then i have the table "Borrowed" which looks like this
+---------------+-------------------+-------+-----+----------------------+-----------------------------+
| Field | Type | Null | Key | Default | Extra |
+---------------+-------------------+-------+-----+----------------------+-----------------------------+
| id | int(11) | NO | PRI | None | auto_increment |
| item_id | int(11) | NO | | NULL | |
| date_borrowed | timestamp | NO | | CURRENT_TIMESTAMP | |
| return_by | datetime | NO | | None | |
| returned | enum('No','Yes') | NO | | No | |
| borrower_id | int(11) | NO | | None | |
| time_returned | timestamp | Yes | | CURRENT_TIMESTAMP | ON UPDATE CURRENT_TIMESTAMP |
+---------------+-------------------+-------+-----+----------------------+-----------------------------+
Now what i want to do is take the "date_borrowed" from "Borrowed" + "time_allowed" + "days_allowed" from the "Category" table to create the datetime value for "return_by" in the "Borrowed" table.
So if the "date_borrowed" is "2016-01-01 12:00:00" and a dvd is borrowed then the "return_by" should be "2016-01-04 12:00:00".
Is this possible to do through Triggers ?
Any and all feedback is much appreciated.
UPDATE:
CREATE TABLE `borrowed` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`item_id` int(11) DEFAULT NULL,
`date_borrowed` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`return_by` datetime NOT NULL,
`returned` enum('No','Yes') CHARACTER SET utf8 NOT NULL DEFAULT 'No',
`borrower_id` int(11) NOT NULL,
`time_returned` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
KEY `borrower_id_idx` (`borrower_id`),
KEY `item_id_idx` (`item_id`),
CONSTRAINT `borrowed_ibfk_1` FOREIGN KEY (`item_id`) REFERENCES `items` (`id`) ON DELETE SET NULL ON UPDATE CASCADE,
CONSTRAINT `borrower_id` FOREIGN KEY (`borrower_id`) REFERENCES `borrower` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB AUTO_INCREMENT=13 DEFAULT CHARSET=utf8 COLLATE=utf8_bin
CREATE TABLE `category` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(100) CHARACTER SET utf8 NOT NULL,
`time_allowed` time NOT NULL,
`days_allowed` varchar(400) COLLATE utf8_bin NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8 COLLATE=utf8_bin
CREATE TABLE `items` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`item_name` varchar(150) CHARACTER SET utf8 NOT NULL,
`item_uniqueid` varchar(100) CHARACTER SET utf8 NOT NULL COMMENT 'This can be a Serial Number or a ISBN number. But has to be unique for that item',
`item_status` enum('Ok','Damaged','Broken') CHARACTER SET utf8 NOT NULL,
`item_comment` longtext CHARACTER SET utf8,
`item_retired` enum('No','Yes') CHARACTER SET utf8 NOT NULL DEFAULT 'No',
`item_dop` date NOT NULL COMMENT 'item_dop = Item Date Of Purchaes',
`item_category` int(11) NOT NULL,
PRIMARY KEY (`id`),
KEY `id_category_idx` (`item_category`),
CONSTRAINT `id_category` FOREIGN KEY (`item_category`) REFERENCES `category` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8 COLLATE=utf8_bin
First you need to allow NULLs for the return_by column:
ALTER TABLE `borrowed`
ALTER `return_by` DROP DEFAULT;
ALTER TABLE `borrowed`
CHANGE COLUMN `return_by` `return_by` DATETIME NULL AFTER `date_borrowed`;
Then create a BEFORE INSERT trigger for the borrowed table:
DELIMITER //
CREATE TRIGGER `borrowed_before_insert` BEFORE INSERT ON `borrowed` FOR EACH ROW BEGIN
set new.return_by = (
select new.date_borrowed
+ interval c.days_allowed day
+ interval time_to_sec(c.time_allowed) second
from items i
join category c on c.id = i.item_category
where i.id = new.item_id
);
END//
DELIMITER ;
SQLFiddle-Demo
If you ever update the date_borrowed column, you will also need an UPDATE trigger to ajust the return_by value.
Assuming that you time_allowed is in HOUR, your days_allowed is in number of days (an not a varchar for string) and the two tables are related by a column relation_key and key you could suing a select llike this
select TIMESTAMPADD(HOUR, c.time_allowed,
TIMESTAMPADD( DAY ,c.days_allowed,b.date_borrowed) )
from Borrowed as b
inner join catogory on b.relation_key = c.key
Related
I have two mysql tables, table A and Table B.
Table B contains publication names and ids.
Table A contains reference information and id of the publication from the publication name.
I need to update some values in Table A, I am able to do it for rest of the values using simple update command:
UPDATE reference SET issue ='4',
doi ='',
url ='https://app.dimensions.ai/details/publication/pub.1077608314' ,
issn=''
where id = 9433356;
though I also need to update one of the column, publication. Now I have to value of the publication. I was wondering if I can write this in one single query, where i insert the value in table B or if the value exists in table b, get the id and update the value in table A.
Table A definitions:
CREATE TABLE `reference` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`end_page` int(11) DEFAULT NULL,
`number` int(11) DEFAULT NULL,
`published` datetime DEFAULT NULL,
`reference_id` varchar(64) COLLATE utf8_bin DEFAULT NULL,
`start_page` int(11) DEFAULT NULL,
`volume` int(11) DEFAULT NULL,
`project` int(11) NOT NULL,
`publication_source` int(11) NOT NULL,
`seed` tinyint(1) NOT NULL DEFAULT '0',
`accession_number` varchar(128) COLLATE utf8_bin DEFAULT NULL,
`database_name` varchar(1024) COLLATE utf8_bin DEFAULT NULL,
`has_full_text` tinyint(1) NOT NULL DEFAULT '0',
`external_id` varchar(255) COLLATE utf8_bin DEFAULT NULL,
`model_seed` varchar(128) COLLATE utf8_bin DEFAULT 'NONE',
`url` varchar(2083) COLLATE utf8_bin DEFAULT NULL,
`doi` varchar(1024) COLLATE utf8_bin DEFAULT NULL,
`issue` varchar(64) COLLATE utf8_bin DEFAULT NULL,
`issn` varchar(1024) COLLATE utf8_bin DEFAULT NULL,
`call_number` varchar(2083) COLLATE utf8_bin DEFAULT NULL,
`work_type` varchar(1024) COLLATE utf8_bin DEFAULT NULL,
`notes` varchar(10000) COLLATE utf8_bin DEFAULT NULL,
`custom_tags` blob,
PRIMARY KEY (`id`),
KEY `FK_reference_project` (`project`),
KEY `FK_reference_publication_source` (`publication_source`),
CONSTRAINT `FK_reference_project`
FOREIGN KEY (`project`)
REFERENCES `project` (`id`),
CONSTRAINT `FK_reference_publication_source`
FOREIGN KEY (`publication_source`)
REFERENCES `publicationsource` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=10512575 DEFAULT CHARSET=utf8 COLLATE=utf8_bin
Table B definition
CREATE TABLE publicationsource (
id int(11) NOT NULL AUTO_INCREMENT,
name varchar(128) COLLATE utf8_bin DEFAULT NULL,
type varchar(16) COLLATE utf8_bin DEFAULT NULL,
PRIMARY KEY (id),
KEY UK_publicationsource_type_name (type,name)
) ENGINE=InnoDB AUTO_INCREMENT=10921959 DEFAULT CHARSET=utf8 COLLATE=utf8_bin
You can't do the UPDATE of reference in the same statement if you need to INSERT a new row to publicationsource. You would have to do the INSERT and then do the UPDATE. You can get the latest auto-increment id generated by that INSERT using LAST_INSERT_ID():
INSERT INTO publicationsource ...;
UPDATE reference
SET r.issue ='4',
doi ='',
url ='https://app.dimensions.ai/details/publication/pub.1077608314' ,
issn='',
publication_source = LAST_INSERT_ID()
WHERE id = 9433356;
If the publicationsource row you need already exists, then you can use a scalar subquery to get it:
UPDATE reference
SET r.issue ='4',
doi ='',
url ='https://app.dimensions.ai/details/publication/pub.1077608314' ,
issn='',
publication_source = (
SELECT id FROM publicationsource
WHERE type = ? AND name = ? LIMIT 1
)
WHERE id = 9433356;
We can run a query to create the entry in the parent table id it does not already exist before running our insert or update query on the references table.
This means that we can run the same queries, without errors, whether the entries exist or not.
INSERT INTO publicationsource
(id, name, type)
SELECT DISTINCT
1,
'publication name 1',
'type name 1'
WHERE NOT EXISTS
(SELECT id
FROM publicationsource
WHERE id = 1);
✓
INSERT INTO reference
(id, publication_source, project, issue, doi, url, issn) VALUES
(9433356, 1, 1, '4', '', 'https://app.dimensions.ai/details/publication/pub.1077608314', '' )
ON DUPLICATE KEY UPDATE
issue ='4', doi ='', url ='https://app.dimensions.ai/details/publication/pub.1077608314' ,issn='';
✓
SELECT * FROM project;
| id |
| -: |
| 1 |
SELECT * FROM publicationsource;
id | name | type
-: | :----------------- | :----------
1 | publication name 1 | type name 1
SELECT * FROM reference;
id | end_page | number | published | reference_id | start_page | volume | project | publication_source | seed | accession_number | database_name | has_full_text | external_id | model_seed | url | doi | issue | issn | call_number | work_type | notes | custom_tags
------: | -------: | -----: | :-------- | :----------- | ---------: | -----: | ------: | -----------------: | ---: | :--------------- | :------------ | ------------: | :---------- | :--------- | :----------------------------------------------------------- | :-- | :---- | :--- | :---------- | :-------- | :---- | :----------
9433356 | null | null | null | null | null | null | 1 | 1 | 0 | null | null | 0 | null | NONE | https://app.dimensions.ai/details/publication/pub.1077608314 | | 4 | | null | null | null |
db<>fiddle here
I have a query like
SELECT `table1`.*
FROM `table1`
WHERE `table1`.`table2_id` IN (1,2,6,12,53,666)
and it works more than 20 seconds
Explain looks like:
+----+-------------+--------------------------+------------+-------+-------------------------------------------------------------------------------+----------------------------------+---------+------+-------+----------+-----------------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+--------------------------+------------+-------+-------------------------------------------------------------------------------+----------------------------------+---------+------+-------+----------+-----------------------+
| 1 | SIMPLE | table1 | NULL | range | table2_id | table2_id | 4 | NULL | 74778 | 100.00 | Using index condition |
+----+-------------+--------------------------+------------+-------+-------------------------------------------------------------------------------+----------------------------------+---------+------+-------+----------+-----------------------+
Table looks like
CREATE TABLE `table1` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`table2_id` int(11) NOT NULL,
`table3_id` int(11) NOT NULL,
`field1` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
`field2` int(11) NOT NULL DEFAULT '0',
`created_at` datetime NOT NULL,
`updated_at` datetime NOT NULL,
`field3` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `name_of_index_id` (`table3_id`),
KEY `other_name_of_index` (`field2`),
KEY `table2_id` (`table2_id`)
) ENGINE=InnoDB AUTO_INCREMENT=86623178 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci
You can use index to fetch the result quickly. But, Indexing will take more space to generate and store in the database. So, if you are fine to utilize speed compare to space, Indexing will be used with following SQL statement.
ALTER TABLE `table1` ADD INDEX(`table2_id`);
I have two huge tables from which i have select huge amount of data.
Tables store Purchase Order Details and product information.
PURCHASE_ORDER_DETAILS.
CREATE TABLE `PURCHASE_ORDER_DETAILS` (
`PURCHASE_ORDER_NUMBER_PF` INT(20) NOT NULL,
`PRODUCT_CODE_PF` VARCHAR(32) CHARACTER SET latin1 COLLATE latin1_bin NOT NULL,
`ORDER_QUANTITY` INT(8) DEFAULT NULL,
`UNIT_PRICE` DECIMAL(12,2) DEFAULT NULL,
`ORDER_FULLFILLMENT_DUE_DATE` DATETIME DEFAULT NULL,
`DELIVERY_ADDRESS` VARCHAR(64) CHARACTER SET latin1 COLLATE latin1_bin DEFAULT NULL,
`DELIVERY_CITY` VARCHAR(32) CHARACTER SET latin1 COLLATE latin1_bin DEFAULT NULL,
`DELIVERY_ZIP` BIGINT(10) DEFAULT NULL,
`other columns`
PRIMARY KEY (`PURCHASE_ORDER_NUMBER_PF`,`PRODUCT_CODE_PF`),
KEY `RMAPWBTX_PUCH_ORDE_DLST_INDX` (`DELIVERY_STATE_ID_FK`),
KEY `RMAPWBTX_PUCH_ORDE_DLTY_INDX` (`DELIVERY_TYPE_FK`),
KEY `RMAPWBTX_PUCH_ORDE_TACO_INDX` (`TAX_CODE_FK`),
KEY `RMAPWBMS_PUOR_DETL_PDCO_FK` (`PRODUCT_CODE_PF`),
KEY `RMAPWBTX_PUOR_DETL_TACO_FK` (`TAX_CODE_FK`),
KEY `CREATED_DATE_INDX` (`CREATED_DATE`),
KEY `MODIFIED_DATE_INDX` (`MODIFIED_DATE`),
CONSTRAINT `RMAPWBMS_PUOR_DETL_PDCO_FK` FOREIGN KEY (`PRODUCT_CODE_PF`)
REFERENCES `PRODUCT` (`PRODUCT_CODE_PK`) ON DELETE NO ACTION ON UPDATE NO ACTION,
CONSTRAINT `RMAPWBMS_PUOR_DETL_PONU_FK` FOREIGN KEY
(`PURCHASE_ORDER_NUMBER_PF`) REFERENCES `PURCHASE_ORDER`
(`PURCHASE_ORDER_NUMBER_PK`),
CONSTRAINT `RMAPWBTX_PO_DETL_DSID_FK` FOREIGN KEY
(`DELIVERY_STATE_ID_FK`) REFERENCES `STATE` (`STATE_ID_PK`),
CONSTRAINT `RMAPWBTX_PUOR_DETL_TACO_FK` FOREIGN KEY (`TAX_CODE_FK`)
REFERENCES `TAX` (`TAX_CODE_PK`) ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE=INNODB DEFAULT CHARSET=latin1;
PRODUCT
CREATE TABLE `PRODUCT` (
`PRODUCT_CODE_PK` VARCHAR(32) CHARACTER SET latin1 COLLATE latin1_bin NOT NULL,
`PRODUCT_DESC` VARCHAR(256) CHARACTER SET latin1 COLLATE latin1_bin DEFAULT NULL,
`FEE_BILL_CODE` VARCHAR(32) CHARACTER SET latin1 COLLATE latin1_bin DEFAULT NULL,
`other columns`
PRIMARY KEY (`PRODUCT_CODE_PK`),
KEY `CREATED_DATE_INDX` (`CREATED_DATE`),
KEY `MODIFIED_DATE_INDX` (`MODIFIED_DATE`),
KEY `PRODUCT_EXCO_FK` (`EXPENSE_CODE_ID_FK`),
KEY `FK_PRODUCT_ENTITY_TYPE` (`ENTITY_TYPE_CODE_FK`),
CONSTRAINT `FK_PRODUCT_ENTITY_TYPE` FOREIGN KEY (`ENTITY_TYPE_CODE_FK`) REFERENCES `ENTITY_TYPE` (`ENTITY_TYPE_CODE_PK`)
) ENGINE=INNODB DEFAULT CHARSET=latin1
Below query is taking ~10min to get ~1M records.
EXPLAIN SELECT * FROM
PURCHASE_ORDER_DETAILS POD
JOIN PRODUCT PRD ON POD.PRODUCT_CODE_PF=PRD.PRODUCT_CODE_PK;
+----+-------------+-------+------+----------------------------+-----------------
-----------+---------+-----------------------------------------------+-------+-------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+------+----------------------------+----------------------------+---------+-----------------------------------------------+-------+-------+
| 1 | SIMPLE | PRD | ALL | PRIMARY | NULL | NULL | NULL | 14283 | NULL |
| 1 | SIMPLE | POD | ref | RMAPWBMS_PUOR_DETL_PDCO_FK | RMAPWBMS_PUOR_DETL_PDCO_FK | 34 | REALREMIT_PROD_ALTISOURCE.PRD.PRODUCT_CODE_PK | 40 | NULL |
+----+-------------+-------+------+----------------------------+----------------------------+---------+-----------------------------------------------+-------+---
Edit1:
Above query was an example, below is the actual query where i am trying to fetch 1M records (main table POD has 22M records).
SELECT `some columns`
FROM `REALREMIT_PPIPFC_MIG`.MIGR_ORDER_DENORM MPO
INNER JOIN PURCHASE_ORDER_DETAILS POD
ON MPO.PURCHASE_ORDER_NUMBER_PK=POD.PURCHASE_ORDER_NUMBER_PF
INNER JOIN PRODUCT PRD
ON POD.PRODUCT_CODE_PF=PRD.PRODUCT_CODE_PK
INNER JOIN EXPENSE_CODE EXP
ON PRD.EXPENSE_CODE_ID_FK=EXP.EXPENSE_CODE_ID_PK
WHERE MPO.BATCH_ID=1;
Explain Output for the above query
+----+-------------+-------+--------+-------------------------------------+----------------------------+---------+--------------------------------------------------------+-------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+--------+-------------------------------------+----------------------------+---------+--------------------------------------------------------+-------+-------------+
| 1 | SIMPLE | PRD | ALL | PRIMARY,PRODUCT_EXCO_FK | NULL | NULL | NULL | 14283 | NULL |
| 1 | SIMPLE | EXP | eq_ref | PRIMARY | PRIMARY | 4 | REALREMIT_PROD_ALTISOURCE.PRD.EXPENSE_CODE_ID_FK | 1 | NULL |
| 1 | SIMPLE | POD | ref | PRIMARY,RMAPWBMS_PUOR_DETL_PDCO_FK | RMAPWBMS_PUOR_DETL_PDCO_FK | 34 | REALREMIT_PROD_ALTISOURCE.PRD.PRODUCT_CODE_PK | 40 | NULL |
| 1 | SIMPLE | MPO | ref | MIGR_PO_NBR_INDX,MIGR_BATCH_ID_INDX | MIGR_PO_NBR_INDX | 4 | REALREMIT_PROD_ALTISOURCE.POD.PURCHASE_ORDER_NUMBER_PF | 1 | Using where |
+----+-------------+-------+--------+-------------------------------------+----------------------------+---------+--------------------------------------------------------+-------+-------------+
4 rows in set (0.20 sec)
Both database have same charset
Columns used in join have the same collate
Both tables have same charset
I have created new table in which primary key is concatenated column - PURHCASE_ORDER_NUMBER_PF and PRODUCT_CODE_PF and then i have added a new index on PRODUCT_CODE_PF
Will index be used in this case and/or is this the best way to make use of index in join.
Thanks
These may help:
MPO: INDEX(BATCH_ID, PURCHASE_ORDER_NUMBER_PK) -- in this order
EXP: INDEX(EXPENSE_CODE_ID_PK) -- unless it is the PRIMARY KEY
But, without knowing what is in "some columns", I can't predict how much they will help. And it would help to have SHOW CREATE TABLE for MPO and EXP.
How much RAM do you have? What is the value of innodb_buffer_pool_size? I ask because you may be thrashing.
Error: Cannot add or update a child row: a foreign key constraint
fails?
(testlogin.leavetable, CONSTRAINT leavetable_ibfk_1 FOREIGN KEY
(users_id) REFERENCES users (id) ON DELETE CASCADE ON UPDATE CASCADE)
Been getting this message for the last day and a half. Trying to make a one to many (foreign key) relationship between the two tables. Between users:id and leavetable:users_id. When user logs in they get a id. when they submit a form to column hours I'd like for the id to stay with the form data. It is throwing the error when someone creates a new id number and it wont update the leavetable:user_id. It throws the error above.
What's going on? Am I approaching this the right way?
Here's my code:
CREATE TABLE IF NOT EXISTS `users` (
`email` varchar(255) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL,
`id` int(11) NOT NULL,
`password` char(64) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL,
`salt` char(16) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL,
`username` varchar(255) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
CREATE TABLE IF NOT EXISTS `leavetable` (
`hours` int(11) NOT NULL,
`users_id` int(11) DEFAULT NOT NULL,
`id` int(11) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
ALTER TABLE `users`
ADD PRIMARY KEY (`id`) USING BTREE,
ADD UNIQUE KEY `email` (`email`) USING BTREE,
ADD UNIQUE KEY `username` (`username`) USING BTREE;
ALTER TABLE `leavetable`
ADD PRIMARY KEY (`id`) USING BTREE,
ADD KEY `users_id` (`users_id`) USING BTREE;
ALTER TABLE `leavetable`
MODIFY `id` int(11) NOT NULL AUTO_INCREMENT;
-- AUTO_INCREMENT for table `users`
ALTER TABLE `users`
MODIFY `id` int(11) NOT NULL AUTO_INCREMENT;
ALTER TABLE `leavetable`
ADD CONSTRAINT `leavetable_ibfk_1` FOREIGN KEY (`users_id`) REFERENCES
`users` (`id`) ON DELETE CASCADE ON UPDATE CASCADE;
my table structure:
+---------------------+
| Tables_in_testlogin |
+---------------------+
| leavetable |
| users |
+---------------------+
+----------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+----------+--------------+------+-----+---------+----------------+
| email | varchar(255) | NO | UNI | NULL | |
| id | int(11) | NO | PRI | NULL | auto_increment |
| password | char(64) | NO | | NULL | |
| salt | char(16) | NO | | NULL | |
| username | varchar(255) | NO | UNI | NULL | |
+----------+--------------+------+-----+---------+----------------+
5 rows in set (0.01 sec)
+----------+---------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+----------+---------+------+-----+---------+----------------+
| hours | int(11) | NO | | NULL | |
| users_id | int(11) | NO | MUL | NULL | |
| id | int(11) | NO | PRI | NULL | auto_increment |
+----------+---------+------+-----+---------+----------------+
3 rows in set (0.01 sec)
php code:
mysql_select_db("testlogin", $con);
$sql="INSERT INTO leavetable (hours)
VALUES
('$_POST[hours]')";
if (!mysql_query($sql,$con))
{
die('Error: ' . mysql_error());
}
$sql="INSERT INTO leavetable (hours)
VALUES
('$_POST[hours]')";
The above sql code does not contain any reference to user id. How should mysql guess which user this leave entry belong to? Include tge user id both in the columns and the values section of the insert statement. Probably you should store the user id in the php session.
Looks like I've got it going. I basically have a hidden field in my form with the users id. when the form is submitted it is submitted with the form information to leavetable. Not sure if this is the right way to go about it but it seems to work.
form code:
<input type="number" name="hours" value="" />
<label>id: </label>
<input type="text" name="id" value="<?php
echo htmlentities($_SESSION['user']['id'], ENT_QUOTES, 'UTF-8');
?>" /> <br /><br />
<input type="submit" class="btn btn-info" name="submit" value="Submit" />
sql:
$sql = "INSERT INTO leavetable ( hours, users_id )
VALUES ( '{$mysqli->real_escape_string($_POST['hours'])}',
'{$mysqli->real_escape_string($_POST['id'])}' )";
$insert = $mysqli->query($sql);
It works. Is it the best way to go about this?
Why does lean_users show NULL in the ref column? This causes my query to use a temporary table and a filesort later (when I've added more joins)...
14:45:21 (60) > EXPLAIN select * from users u inner join lean_users lu on u.id = lu.user_id;
+----+-------------+-------+--------+---------------+---------+---------+----------------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+--------+---------------+---------+---------+----------------+------+-------------+
| 1 | SIMPLE | lu | index | PRIMARY | PRIMARY | 4 | NULL | 358 | Using index |
| 1 | SIMPLE | u | eq_ref | PRIMARY | PRIMARY | 4 | nwa.lu.user_id | 1 | |
+----+-------------+-------+--------+---------------+---------+---------+----------------+------+-------------+
users table
14:45:24 (61) > show create table users;
+-------+-----------------------------------------------------------------------------+
| Table | Create Table |
+-------+-----------------------------------------------------------------------------+
| users | CREATE TABLE `users` (
`id` int(11) NOT NULL auto_increment,
`email` varchar(255) default NULL,
`first_name` varchar(50) NOT NULL,
`last_name` varchar(50) NOT NULL,
`address1` varchar(255) NOT NULL,
`address2` varchar(255) default NULL,
`city` varchar(25) NOT NULL,
`state` mediumint(9) default NULL,
`zip` varchar(10) NOT NULL,
`phone` varchar(20) default NULL,
`country` smallint(6) NOT NULL,
`username` varchar(10) NOT NULL,
`password` varchar(50) default NULL,
`cdate` datetime NOT NULL,
`last_used` timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
`level` varchar(25) default 'user',
PRIMARY KEY (`id`),
) ENGINE=InnoDB AUTO_INCREMENT=38076 DEFAULT CHARSET=utf8 |
+-------+-----------------------------------------------------------------------------+
lean_users table
14:45:40 (62) > show create table lean_users;
+-------------+-----------------------------------------------------------------------------+
| Table | Create Table |
+-------------+-----------------------------------------------------------------------------+
| lean_users | CREATE TABLE `lean_users` (
`user_id` int(11) NOT NULL,
PRIMARY KEY (`user_id`),
CONSTRAINT `lean_users_ibfk_1` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 |
+-------------+-----------------------------------------------------------------------------+
Why does lean_users show NULL in the ref column?
Because this table is leading in the join and you don't filter on any indexed fields.
This means that each record should be read and evaluated.