Using composite key as a foreign key in mysql - mysql

My Tables
Fee Table
CREATE TABLE IF NOT EXISTS `fee` (
`feeNumber` int(11) NOT NULL,
`feeName` varchar(255) NOT NULL,
`feeDescription` varchar(255) DEFAULT NULL,
`feeAmount` varchar(255) NOT NULL,
`universityName` varchar(255) NOT NULL
)
ADD PRIMARY KEY (`feeNumber`,`feeName`,`feeAmount`)
Housing Table
CREATE TABLE IF NOT EXISTS `housing` (
`housingOfficeNumber` int(11) NOT NULL,
`housingOfficeName` varchar(50) NOT NULL DEFAULT '',
`housingOfficeType` varchar(50) DEFAULT NULL,
`housingOfficePhone` decimal(18,0) DEFAULT NULL,
`housingOfficeRoomDeposit` varchar(50) DEFAULT NULL,
`studentStatusName` varchar(50) DEFAULT NULL,
`housingFeeNumber` int(11) NOT NULL,
`housingFeeName` varchar(255) NOT NULL,
`housingFee` int(255) DEFAULT NULL,
`hOffTrm` varchar(50) DEFAULT NULL,
`universityName` varchar(50) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
What I'm trying to do is reference the feeAmount,feeNumber, and feeName from the fee table and add it to the housingfee, housingfeeName, and housingFeenumber columns in the housing table. Since the feeAmount and feeName columns are not unique I decided to make a composite key out of feeNumber, feeName, and feeAmount. The only part of the composite key I really need referenced is feeAmount. feeName and feeNumber are not really important. using phpmyadmin.

No, no, no. In general, I think it is best to avoid compound primary keys. In this case, in particular, you do not want the fee amount or name to be part of the key. In order to access the row, you need to know the amount. That seems very difficult to implement.
I am guessing that an auto incremented primary key will work just fine. You can then add a separate unique constraint on other columns. So:
CREATE TABLE IF NOT EXISTS `fee` (
`feeNumber` int(11) NOT NULL auto_increment primary key,
`feeName` varchar(255) NOT NULL,
`feeDescription` varchar(255) DEFAULT NULL,
`feeAmount` varchar(255) NOT NULL,
`universityName` varchar(255) NOT NULL,
unique (feeName)
);
Then, another table would have feeNumber with an appropriate foreign key reference. Through the reference, you can get other information -- such as the name and amount -- using a join.

Related

How to make mysql table column as KEY, when already another column is set as PRIMARY KEY

In our mysql database, one table say "mytable" is having coumn mobile_no as primary key. But we are in need to make another column also as key. So that I can use that column in where condition.
Show create of table is below-:
CREATE TABLE `report_data` (
`api_request_id` int(11) NOT NULL AUTO_INCREMENT,
`emailid` varchar(100) NOT NULL,
`api_recipient_data` longtext,
`request_params` varchar(255) DEFAULT NULL,
`sent_date` date DEFAULT NULL,
`sent_time` datetime NOT NULL,
`status` tinyint(1) NOT NULL DEFAULT '0' COMMENT '1-processed, 2-success, 3-in-bounce, 4-invalid-domain,5-in-unsubscribe, 6-in-scrubbing',
`api_userid` int(11) DEFAULT NULL,
`domain_name` varchar(255) DEFAULT NULL,
PRIMARY KEY (`api_request_id`,`emailid`),
KEY `sent_date` (`sent_date`)
);
I want to add one new column to this existing table and make that column as KEY.
we want to add one column d_name and want it to make it as KEY
ALTER TABLE report_data
ADD COLUMN d_name {column definition} ,
ADD INDEX (d_name);
sample fiddle

i have a challenge relating what should be primary key and foreign key in my database tables

i am designing database tables for a real estate company. my head is clogged up .i cant figure out how to decide which columns will become primary keys,foreign keys and/or composite keys.
i have four tables; location, floors , typeOfProperty and features.
location table is the most basic table that has columns; locationLong, locationLat,locationName and propertyName. locationlong is the primary key in this table.
i created the location table and used locationlong as primary key because i figured out that every point on earth has a unique location Longitude.this is if i consider that positive and negative values are always unique.(i stand to be collected).
i have noted however that there are situations where i would want to identify a property on a certain location that has a building that has more than one floor.therefore i would like to figure out how my floors table needs to be constructed. i am thinking of having a location long column and a second
column called floor number such that both these columns will make composite primary key of this table.
There is a third table called typeOfProperty. this is the table where i want to have different columns that select the type of property that can be on a particular floor. i.e a floor can have many houses to buy, many houses to let, a commercial property to sell, etc. so i have created the following columns;
hseBuyOrLetOrFurn ENUM('buy', 'let', 'furn') - SELECT IF HOUSE IS TO BUY, LET,
OR FULLY FURNISHED
comspaceBuyOrLease ENUM('buy', 'lease') - TO SELECT IF COMMERCIAL SPACE IS BUY
OR LEASE
cost INT -- TO CAPTURE COST OF PROPERTY ETC.
i would want to know what to use as primary key in this table.
there is a third table called general features . this table has columns that has columns that show the features of a particular type of property e.g it has a column for No of bedrooms, cctv,swimming pool, bathrooms,lifts, etc.
i have other similar tables to the general features as shown in the code below.
please assist me to know how i should figure out primary and foreign keys in this table.
CREATE TABLE `location` (
`locationLong` decimal(11,8) NOT NULL,
`locationLat` decimal(10,8) NOT NULL,
`locationName` varchar(35) NOT NULL,
`houseNumber` int(11) DEFAULT NULL,
PRIMARY KEY (`locationLong`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1
CREATE TABLE `floors` (
`locationLong` decimal(11,8) NOT NULL,
`locationLat` decimal(10,8) NOT NULL,
`locationName` varchar(35) NOT NULL,
`id` int(11) DEFAULT NOT NULL AUTO_INCREMENT,
PRIMARY KEY (`ld`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1
CREATE TABLE `propertytype` (
`locationLong` decimal(11,8) NOT NULL,
`locationLat` decimal(10,8) NOT NULL,
`hseBuyOrLetOrFurn` enum('buy','let','furn') DEFAULT NULL,
`bedrooms` int(11) DEFAULT NULL,
`gatedOrSloneOrApart` enum('gated','slone','apart') DEFAULT NULL,
`hotelOr` tinyint(4) DEFAULT NULL,
`gdwnBuyOrLease` enum('gdwn','lease') DEFAULT NULL,
`landBuyOrLease` enum('buy','lease') DEFAULT NULL,
`comspaceBuyOrLease` enum('buy','lease') DEFAULT NULL,
`twoDImage` blob,
`threeDImage` blob,
`vRVideo` blob,
`cost` int(10) unsigned NOT NULL,
`location_locationLong` decimal(11,8) NOT NULL,
PRIMARY KEY (`locationLong`),
KEY `fk_propertyType_location_idx` (`location_locationLong`),
CONSTRAINT `fk_propertyType_location` FOREIGN KEY (`location_locationLong`) REFERENCES `area` (`locationLong`) ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE=InnoDB DEFAULT CHARSET=latin1
CREATE TABLE `generalfeatures` (
`locationLong` decimal(11,8) NOT NULL,
`locationLat` decimal(10,8) NOT NULL,
`livingAreaAndSize` int(11) NOT NULL,
`bedrooms` int(11) NOT NULL,
`bathrooms` int(11) NOT NULL,
`masterEnsuite` tinyint(1) NOT NULL,
`bedroomsWithBathrooms` tinyint(4) NOT NULL,
`kitchenAndSize` tinyint(4) NOT NULL,
`parkingAndSlots` tinyint(4) NOT NULL,
`swimmingPool` tinyint(1) NOT NULL,
`liftsAndNumber` tinyint(4) NOT NULL,
`CCTV` tinyint(1) NOT NULL,
`sizeOfLand` int(11) NOT NULL,
`borehole` tinyint(1) NOT NULL,
`propertyType_locationLong` decimal(11,8) NOT NULL,
PRIMARY KEY (`locationLong`),
KEY `fk_generalFeatures_propertyType1_idx` (`propertyType_locationLong`),
CONSTRAINT `fk_generalFeatures_propertyType1` FOREIGN KEY (`propertyType_locationLong`) REFERENCES `propertytype` (`locationLong`) ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE=InnoDB DEFAULT CHARSET=latin1
CREATE TABLE `hotelfeatures` (
`locationLong` decimal(11,8) NOT NULL,
`locationLat` decimal(10,8) NOT NULL,
`conference` tinyint(1) NOT NULL,
`fibreCable` tinyint(1) NOT NULL,
`spa` tinyint(1) NOT NULL,
`freshOutdoor` tinyint(1) NOT NULL,
`laundryFacilities` tinyint(1) NOT NULL,
`entertainment` tinyint(1) NOT NULL,
`wifi` tinyint(1) NOT NULL,
`propertyType_locationLong` decimal(11,8) NOT NULL,
PRIMARY KEY (`locationLong`),
KEY `fk_hotelFeatures_propertyType1_idx` (`propertyType_locationLong`),
CONSTRAINT `fk_hotelFeatures_propertyType1` FOREIGN KEY (`propertyType_locationLong`) REFERENCES `propertytype` (`locationLong`) ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE=InnoDB DEFAULT CHARSET=latin1
CREATE TABLE `outdoorfeatures` (
`locationLong` decimal(11,8) NOT NULL,
`locationLat` decimal(10,8) NOT NULL,
`gym` tinyint(1) NOT NULL,
`matureGardens` tinyint(1) NOT NULL,
`partyArea` tinyint(1) NOT NULL,
`gardenAndSize` tinyint(1) NOT NULL,
`waterFront` tinyint(1) NOT NULL,
`propertyType_locationLong` decimal(11,8) NOT NULL,
PRIMARY KEY (`locationLong`),
KEY `fk_outdoorFeatures_propertyType1_idx` (`propertyType_locationLong`),
CONSTRAINT `fk_outdoorFeatures_propertyType1` FOREIGN KEY (`propertyType_locationLong`) REFERENCES `propertytype` (`locationLong`) ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE=InnoDB DEFAULT CHARSET=latin1
I want to have a general idea how the location table that have location details, links to floors table that has details of floor type links to the propertytype table that links to different property type and finally how this property type table links to the generalfeatures, hotel features and indoor features table.
You have a table to hold property main data (this table later you add to it more fields as required until I get the final design for table)
Ex: main_property_file( property_id PK , address, GPS_location )
Then you need to know is it for lease or sale ,
Build lookup table hold this , ex: property_for(typefor PK, name this)
And going to add a filed in previous main_property_file for typefor filed as foreign key
And so on until you put all business data structure , then going to review the tables and relation for consistency, you can put this in visual tool if you cannot imagine the relation and the data each table hold, and finally ask your model with query to find information or enter new data and so on to be sure your table design is complete and review the constraints too.

How to set primary key with auto increment in MYSQL

CREATE TABLE `journal` (
`yearr` int(4) NOT NULL,
`monthh` char(3) NOT NULL,
`volume` int(4) NOT NULL,
`issue` int(4) NOT NULL,
`pagefromto` varchar(10) NOT NULL,
`pissn` varchar(20) NOT NULL,
`eissn` varchar(20) DEFAULT NULL,
`name` varchar(50) NOT NULL,
`author1` varchar(10) DEFAULT NULL,
`author2` varchar(10) DEFAULT NULL,
`doc` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
)
ALTER TABLE `journal`
ADD PRIMARY KEY (`yearr`,`volume`,`issue`,`pagefromto`,`pissn`);
I need to add another key with auto increment to the above table structure
Your question is a bit confusing. You say you want to add a second primary key which will be auto increment... This doesn't make sense. They are called PRIMARY keys for a reason. There is only one primary key on a table as it is the, well, Primary key.
What I think you want to do is have a auto increment ID to use as the PK, which you could include in your create table like Arshad answered.
At that point, what you want to do is use your auto increment ID as the primary key (the same way you did with your PK, but put only the new ID in the PK, not the rest of your fields.), and you will want to use a unique index to make sure the combination of (yearr,volume,issue,pagefromto,pissn) doesn't repeat.
See this document to get more info on index creation
Note that if your table is already created, you'll have to delete the old primary key before you can add it on the ID.
You can use this query. This will create table with "id" as AutoIncrement and primary key
CREATE TABLE
tbl_employee (
id int(11) NOT NULL AUTO_INCREMENT,
employee_id int(4) NOT NULL,
employee_no int(6) NOT NULL,
employee_name varchar(60) NOT NULL,
department_id int(4) NOT NULL,
designation_id int(4) NOT NULL,
hired_date date NOT NULL,
salary int(10) NOT NULL,
PRIMARY KEY(id)
)

MySQL: Optimizing JOINs to find non-matching records

We have a host management system (let's call it CMDB), and a DNS system, each using different tables. The former syncs to the latter, but manual changes cause them to get out of sync. I would like to craft a query to find aliases in CMDB that do NOT have a matching entry in DNS (either no entry, or the name/IP is different)
Because of the large size of the tables, and the need for this query to run frequently, optimizing the query is very important.
Here's what the tables look like:
cmdb_record: id, ipaddr
cmdb_alias: record_id, host_alias
dns_entry: name, ipaddr
cmdb_alias.record_id is a foreign key from cmdb_record.id, so that one IP address can have multiple aliases.
So far, here's what I've come up with:
SELECT cmdb_alias.host_alias, cmdb_record.ipaddr
FROM cmdb_record
INNER JOIN cmdb_alias ON cmdb_alias.record_id = cmdb_record.id
LEFT JOIN dns_entry
ON dns_entry.ipaddr = cmdb_record.ipaddr
AND dns_entry.name = cmdb_alias.host_alias
WHERE dns_entry.ipaddr IS NULL OR dns_entry.name IS NULL
This seems to work, but takes a very long time to run. Is there a better way to do this? Thanks!
EDIT: As requested, here are the SHOW CREATE TABLEs. There are lots of extra fields that aren't particularly relevant, but included for completeness.
Create Table: CREATE TABLE `cmdb_record` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`ip_version` int(11) DEFAULT NULL,
`ipaddr` varchar(40) DEFAULT NULL,
`ipaddr_numeric` decimal(40,0) DEFAULT NULL,
`block_id` int(11) NOT NULL,
`record_commented` tinyint(1) NOT NULL,
`mod_time` datetime NOT NULL,
`deleted` tinyint(1) NOT NULL,
`deleted_date` datetime DEFAULT NULL,
`record_owner` varchar(50) DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `ipaddr` (`ipaddr`),
KEY `cmdb_record_fe30f0f7` (`ipaddr`),
KEY `cmdb_record_2b8b575` (`ipaddr_numeric`),
KEY `cmdb_record_45897ef2` (`block_id`),
CONSTRAINT `block_id_refs_id_ed6ed320` FOREIGN KEY (`block_id`) REFERENCES `cmdb_block` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=104427 DEFAULT CHARSET=latin1
Create Table: CREATE TABLE `cmdb_alias` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`host_alias` varchar(255) COLLATE latin1_general_cs NOT NULL,
`record_id` int(11) NOT NULL,
`record_order` int(11) NOT NULL,
PRIMARY KEY (`id`),
KEY `cmdb_alias_fcffc3bb` (`record_id`),
KEY `alias_lookup` (`host_alias`),
CONSTRAINT `record_id_refs_id_8169fc71` FOREIGN KEY (`record_id`) REFERENCES `cmdb_record` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=155433 DEFAULT CHARSET=latin1 COLLATE=latin1_general_cs
Create Table: CREATE TABLE `dns_entry` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`rec_grp_id` varchar(40) NOT NULL,
`parent_id` int(11) NOT NULL,
`domain_id` int(11) DEFAULT NULL,
`name` varchar(255) DEFAULT NULL,
`type` varchar(6) DEFAULT NULL,
`ipaddr` varchar(255) DEFAULT NULL,
`ttl` int(11) DEFAULT NULL,
`prio` int(11) DEFAULT NULL,
`status` varchar(20) NOT NULL,
`op` varchar(20) NOT NULL,
`mod_time` datetime NOT NULL,
`whodunit` varchar(50) NOT NULL,
`comments` longtext NOT NULL,
PRIMARY KEY (`id`),
KEY `dns_entry_a2431ea` (`domain_id`),
KEY `dns_entry_52094d6e` (`name`)
) ENGINE=InnoDB AUTO_INCREMENT=49437 DEFAULT CHARSET=utf8
If you don't have one already, create an index on dns_entry(ipaddr, name). This might be all you need to speed the query.

Foreign key constraint fails during `drop table`

I have a strange problem in which I'm not able to delete a table as a foreign key constraint fails. The scenario is as follows.
I'm trying to drop the table departments from my DB, the structure for which is as follows:
show create table `departments`
CREATE TABLE `departments` (
`dept_id` int(11) NOT NULL AUTO_INCREMENT,
`dept_name` varchar(50) NOT NULL,
PRIMARY KEY (`dept_id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1
Now, the only other table in the database that has department_id is the employee table:
show create table employee
CREATE TABLE `employee` (
`emp_id` varchar(20) NOT NULL,
`role` varchar(10) DEFAULT NULL,
`password` varchar(500) DEFAULT NULL,
`division_id` int(20) DEFAULT NULL,
`email_bb` varchar(100) DEFAULT NULL,
`is_active` tinyint(1) NOT NULL,
`date_joining` date DEFAULT NULL,
`date_confirmation` date DEFAULT NULL,
`date_appraisal` date DEFAULT NULL,
`date_leaving` date DEFAULT NULL,
`first_name` varchar(100) DEFAULT NULL,
`middle_name` varchar(100) DEFAULT NULL,
`last_name` varchar(100) DEFAULT NULL,
`sex` varchar(1) DEFAULT NULL,
`dob` date DEFAULT NULL,
`email_other` varchar(100) DEFAULT NULL,
`contact` varchar(100) DEFAULT NULL,
`present_addr` varchar(1000) DEFAULT NULL,
`perma_addr` varchar(1000) DEFAULT NULL,
PRIMARY KEY (`emp_id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1
As you can see, none of these tables are related via foreign keys. So why do I get this error when trying to drop the department table:
#1217 - Cannot delete or update a parent row: a foreign key constraint fails
Is there a better way (and hopefully, simpler) way to see the foreign keys defined? What might be going wrong?
show create table doesn't show incoming FK restraints (e.g. FK is specified in child table, not parent)
So there is a possibility that you have another table with a FK constraint to that table. I usually dump the schema of the database, which shows all FK constraints.