I'm very new in MySQL and im making a school project. I have this table:
CREATE TABLE IF NOT EXISTS `Reserva` (
`idReservacion` int(10) NOT NULL AUTO_INCREMENT,
`importe` int(10) DEFAULT NULL,
`fecha` date DEFAULT NULL,
`idCliente` int(11) DEFAULT NULL,
PRIMARY KEY (`idReservacion`),
KEY `idCliente` (`idCliente`),
CONSTRAINT `Reserva_ibfk_1` FOREIGN KEY (`idCliente`) REFERENCES `Cliente` (`idcliente`)
) ENGINE=InnoDB AUTO_INCREMENT=60001 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
And im triying to make Importe a generated field by an update using the next tables
CREATE TABLE IF NOT EXISTS `PaseDeAbordar` (
`idPaseDeAbordar` int(11) NOT NULL AUTO_INCREMENT,
`hora` time DEFAULT NULL,
`idReservacion` int(5) NOT NULL,
`idAsiento` varchar(5) COLLATE utf8_unicode_ci NOT NULL,
`idVuelo` int(11) NOT NULL,
`precioc` int(10) DEFAULT NULL,
PRIMARY KEY (`idPaseDeAbordar`),
KEY `idReservacion` (`idReservacion`),
KEY `idAsiento` (`idAsiento`),
KEY `idVuelo` (`idVuelo`),
CONSTRAINT `PaseDeAbordar_ibfk_1` FOREIGN KEY (`idVuelo`) REFERENCES `Vuelo` (`idvuelo`),
CONSTRAINT `PaseDeAbordar_ibfk_2` FOREIGN KEY (`idReservacion`) REFERENCES `Reservacion` (`idreservacion`),
CONSTRAINT `PaseDeAbordar_ibfk_3` FOREIGN KEY (`idAsiento`) REFERENCES `Asiento` (`idasiento`)
) ENGINE=InnoDB AUTO_INCREMENT=225001 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
Pasedeabordar has the foreign keys from Vuelo and Asiento, this is the structure of those:
CREATE TABLE IF NOT EXISTS `Asiento` (
`idAsiento` varchar(5) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL,
`idClase` int(11) NOT NULL,
`precio` int(11) NOT NULL,
PRIMARY KEY (`idAsiento`),
KEY `idClase` (`idClase`),
CONSTRAINT `Asiento_ibfk_1` FOREIGN KEY (`idClase`) REFERENCES `Clase` (`idclase`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
Vuelo:
CREATE TABLE IF NOT EXISTS `Vuelo` (
`idVuelo` int(8) NOT NULL AUTO_INCREMENT,
`matriculaAvion` varchar(10) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL,
`origen` varchar(4) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL,
`destino` varchar(4) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL,
`fechaVuelo` date NOT NULL,
`horaSalida` time NOT NULL,
`horaLlegada` time NOT NULL,
`duracion` time NOT NULL,
`tieneEscala` varchar(2) CHARACTER SET utf8 COLLATE utf8_unicode_ci DEFAULT 'NO',
`precio` int(10) NOT NULL,
PRIMARY KEY (`idVuelo`),
KEY `origen` (`origen`),
KEY `destino` (`destino`),
KEY `matriculaAvion` (`matriculaAvion`),
CONSTRAINT `Vuelo_ibfk_1` FOREIGN KEY (`origen`) REFERENCES `Terminal` (`idterminal`),
CONSTRAINT `Vuelo_ibfk_2` FOREIGN KEY (`destino`) REFERENCES `Terminal` (`idterminal`),
CONSTRAINT `Vuelo_ibfk_3` FOREIGN KEY (`matriculaAvion`) REFERENCES `Avion` (`matricula`)
) ENGINE=InnoDB AUTO_INCREMENT=5501 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
Importe is suposed to be generated on this way:
reservacion.importe=(precio from asiento+precio from vuelo) where paseabordar.reservacionid=importe.reservacionid
UPDATE reservacion r, pasedeabordar pa, vuelo v, asiento a
SET r.importe=SUM(v.precio+a.precio)
WHERE pa.idreservacion=r.idreservacion
AND pa.idAsiento=a.idAsiento
AND pa.idVuelo=v.idVuelo;
But this generates me an error
Error(1111): Invalid use of group function
Any ideas on what im doing wrong?
SUM() is a group function, which is used to add up cells from the same column. You are simply trying to add up two values from the same row.
r.importe=v.precio+a.precio should work.
By the way, it's considered good practice to join your tables explicitly, like this:
UPDATE reservacion r
JOIN pasedeabordar pa ON pa.idreservacion = r.idreservacion
JOIN vuelo v ON pa.idVuelo = v.idVuelo
JOIN asiento a ON pa.idAsiento = a.idAsiento
SET r.importe = v.precio + a.precio;
Related
"user table" is created successfully. Every columns and types is the same as "users table." But when I create an association table named "user_role," "user table" cannot be called. I only get this error in using MySQL with MariaDB. Installing mysql in windows and using like that is fine. Without changing that table name, is there anything I can do to make it right?
Two tables are dumped because I forget where did I put my original code. But I'll be the same.
CREATE TABLE `user` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`email` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`name` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`course_id` bigint(20) DEFAULT NULL,
`password` varchar(100) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `FKj8ce5cjkm11igsffixdxexrr9` (`course_id`)
) ENGINE=MyISAM AUTO_INCREMENT=5 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
CREATE TABLE `users` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`name` varchar(50) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`email` varchar(50) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`course_id` bigint(20) DEFAULT NULL,
`password` varchar(100) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `course_id` (`course_id`),
CONSTRAINT `users_ibfk_1` FOREIGN KEY (`course_id`) REFERENCES `course` (`id`) ON DELETE SET NULL) ENGINE=InnoDB AUTO_INCREMENT=9 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
CREATE TABLE `role` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`role_name` varchar(50) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
create table `user_role`(
`id` int auto_increment not null,
`user_id_fk` bigint,
`role_id_fk` int,
primary key (`id`),
foreign key (`user_id_fk`) references `user`(`id`),
foreign key (`role_id_fk`) references `role`(`id`)
);
--> references user(id) is not working but references users(id) is working. Is there any way to make it work? Or just change the name?
Suggest you don't have one table name being the plural of another (user vs users); it can lead to typos.
Don't use MyISAM for anything. (with rare exceptions)
If that is a many-to-many mapping table follow the tips in http://mysql.rjweb.org/doc.php/index_cookbook_mysql#many_to_many_mapping_table
The foreign key is across tables defined with different engines(InnoDB and MyISAM):
create table `user_role`(
`id` int auto_increment not null,
`user_id_fk` bigint(20), -- matching data types
`role_id_fk` int(11) -- matching data types
,primary key (`id`)
,foreign key (`role_id_fk`) references `role`(`id`)
,foreign key (`user_id_fk`) references `user`(`id`)
);
db<>fiddle demo
Related: Why doesn't MySQL's MyISAM engine support Foreign keys?
I'm trying to add a foreign key constraint on my schema devair from field user_id of table bluePrints to the PK id of table users but I get an error:
ERROR 1215: Cannot add foreign key constraint
Here are my table definitions:
users:
CREATE TABLE `users` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
`email` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
`password` varchar(60) COLLATE utf8_unicode_ci NOT NULL,
`remember_token` varchar(100) COLLATE utf8_unicode_ci DEFAULT NULL,
`created_at` timestamp NULL DEFAULT NULL,
`updated_at` timestamp NULL DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `users_email_unique` (`email`)
) ENGINE=InnoDB AUTO_INCREMENT=19 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
bluePrints:
CREATE TABLE `bluePrints` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`bluePrintName` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
`description` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
`user_id` int(10) NOT NULL,
`created_at` timestamp NULL DEFAULT NULL,
`updated_at` timestamp NULL DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `uid` (`user_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
And the offending alter table statement:
ALTER TABLE `devair`.`bluePrints`
ADD CONSTRAINT `bp_u`
FOREIGN KEY (user_id)
REFERENCES `devair`.`users` (id)
ON DELETE CASCADE
ON UPDATE CASCADE;
The simple answer would be that you need to do this:
ALTER TABLE table1 ADD CONSTRAINT fk_bp_id FOREIGN KEY (columnFromTable1) REFERENCES table2(columnReferencedFromTable2);
The problem is the 'unsigned' in the bluePrints table. Once it's unsigned, then it works.
Now i have to figure out how to get laravel to use unsigned.
Not sure what else to check/do. I made sure the foreign key data type matches (char(36)) and I ensured the foreign key statement uses the correct syntax
Running this script i get error 1215
USE addm;
CREATE TABLE `addm`.`notificationResource` (
`notificationId` CHAR(36) NOT NULL ,
`resourceId` CHAR(36) NOT NULL ,
PRIMARY KEY (`notificationId`, `resourceId`) ,
INDEX `fk_notificationResource_notification_idx` (`notificationId` ASC) ,
INDEX `fk_notificationResource_resource_idx` (`resourceId` ASC) ,
CONSTRAINT `fk_notificationResource_notification`
FOREIGN KEY (`notificationId` )
REFERENCES `addm`.`notification` (`id` )
ON DELETE NO ACTION
ON UPDATE NO ACTION,
CONSTRAINT `fk_notificationResource_resource`
FOREIGN KEY (`resourceId` )
REFERENCES `addm`.`resource` (`resourceId` )
ON DELETE NO ACTION
ON UPDATE NO ACTION);
commit;
Parent Tables:
CREATE TABLE `resource` (
`resourceId` char(36) NOT NULL,
`resourceName` varchar(255) DEFAULT NULL,
`resourceData` longblob,
PRIMARY KEY (`resourceId`),
UNIQUE KEY `resourceName_UNIQUE` (`resourceName`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8$$
CREATE TABLE `notification` (
`notificationType` varchar(5) CHARACTER SET latin1 NOT NULL,
`id` char(36) CHARACTER SET latin1 NOT NULL,
`aborted` bit(1) DEFAULT NULL,
`attempts` int(11) DEFAULT NULL,
`content` longblob,
`recordDate` datetime DEFAULT NULL,
`sent` bit(1) DEFAULT NULL,
`sentDate` datetime DEFAULT NULL,
`subject` varchar(255) CHARACTER SET latin1 DEFAULT NULL,
`fromUser_id` bigint(20) DEFAULT NULL,
`toUser_id` bigint(20) DEFAULT NULL,
`attachmentName` varchar(100) CHARACTER SET latin1 DEFAULT NULL,
`attachmentData` longblob,
`category` varchar(255) CHARACTER SET latin1 DEFAULT NULL,
`read` tinyint(1) DEFAULT '0',
`locked` tinyint(1) DEFAULT '0',
PRIMARY KEY (`id`),
KEY `FK2D45DD0B7F734EAD` (`toUser_id`),
KEY `FK2D45DD0BE62E629E` (`fromUser_id`),
CONSTRAINT `FK2D45DD0B7F734EAD` FOREIGN KEY (`toUser_id`) REFERENCES `user` (`id`),
CONSTRAINT `FK2D45DD0BE62E629E` FOREIGN KEY (`fromUser_id`) REFERENCES `user` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8$$
I think column CHARACTER SET is different. id char(36) CHARACTER SET latin1 NOT NULL
change CHARACTER SET
At a glance, the database schema looks like this:
The schema has to be in 3rd normal form (and I am aware that hotels.average_rating suggests otherwise, try to oversee that, since the database is not fully designed yet). This is for a tourist recommendation system.
The SQL:
SET SQL_MODE="NO_AUTO_VALUE_ON_ZERO";
SET time_zone = "+00:00";
CREATE TABLE `activities` (
`activity_id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`activity_name` varchar(277) COLLATE utf8_bin NOT NULL,
PRIMARY KEY (`activity_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
CREATE TABLE `bookings` (
`from_date` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`to_date` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
`belong_user` int(10) unsigned NOT NULL,
`belong_hotel` int(10) unsigned NOT NULL,
`rating` int(3) unsigned NOT NULL,
KEY `belong_user` (`belong_user`),
KEY `belong_hotel` (`belong_hotel`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
CREATE TABLE `countries` (
`cuntry_id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`country_name` varchar(20) COLLATE utf8_bin NOT NULL,
PRIMARY KEY (`cuntry_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
CREATE TABLE `hotels` (
`hotel_id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`hotel_name` varchar(128) COLLATE utf8_bin NOT NULL,
`hotel_stars` int(3) NOT NULL,
`hotel_description` text COLLATE utf8_bin NOT NULL,
`average_price` float unsigned NOT NULL,
`average_rating` float unsigned NOT NULL,
`total_rooms` int(10) unsigned NOT NULL,
`free_rooms` int(10) unsigned NOT NULL,
`belong_region` int(10) unsigned NOT NULL,
PRIMARY KEY (`hotel_id`),
KEY `belong_region` (`belong_region`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
CREATE TABLE `hotels_activity_offers` (
`belong_hotel` int(10) unsigned NOT NULL,
`belong_activity` int(10) unsigned NOT NULL,
UNIQUE KEY `belong_hotel_2` (`belong_hotel`,`belong_activity`),
KEY `belong_hotel` (`belong_hotel`),
KEY `belong_activity` (`belong_activity`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
CREATE TABLE `regions` (
`region_id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`belong_country` int(10) unsigned NOT NULL,
`region_name` varchar(255) COLLATE utf8_bin NOT NULL,
PRIMARY KEY (`region_id`),
KEY `belong_country` (`belong_country`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
CREATE TABLE `regions_activity_offers` (
`belong_region` int(10) unsigned NOT NULL,
`belong_activity` int(10) unsigned NOT NULL,
KEY `belong_region` (`belong_region`),
KEY `belong_activity` (`belong_activity`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
CREATE TABLE `users` (
`user_id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`username` varchar(20) COLLATE utf8_bin NOT NULL,
`password` varchar(40) COLLATE utf8_bin NOT NULL COMMENT 'MD5',
`first_name` varchar(20) COLLATE utf8_bin NOT NULL,
`last_name` varchar(20) COLLATE utf8_bin NOT NULL,
`email` varchar(255) COLLATE utf8_bin NOT NULL,
`is_admin` tinyint(1) NOT NULL,
`is_active` tinyint(1) NOT NULL,
PRIMARY KEY (`user_id`),
KEY `is_active` (`is_active`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
CREATE TABLE `users_favourite_activities` (
`belong_user` int(10) unsigned NOT NULL,
`belong_activity` int(10) unsigned NOT NULL,
UNIQUE KEY `belong_user_2` (`belong_user`,`belong_activity`),
KEY `belong_user` (`belong_user`),
KEY `belong_activity` (`belong_activity`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
ALTER TABLE `bookings`
ADD CONSTRAINT `bookings_ibfk_3` FOREIGN KEY (`belong_hotel`) REFERENCES `hotels` (`hotel_id`) ON DELETE CASCADE,
ADD CONSTRAINT `bookings_ibfk_2` FOREIGN KEY (`belong_user`) REFERENCES `users` (`user_id`) ON DELETE CASCADE;
ALTER TABLE `hotels`
ADD CONSTRAINT `hotels_ibfk_1` FOREIGN KEY (`belong_region`) REFERENCES `regions` (`region_id`) ON DELETE CASCADE;
ALTER TABLE `hotels_activity_offers`
ADD CONSTRAINT `hotels_activity_offers_ibfk_2` FOREIGN KEY (`belong_activity`) REFERENCES `activities` (`activity_id`) ON DELETE CASCADE,
ADD CONSTRAINT `hotels_activity_offers_ibfk_1` FOREIGN KEY (`belong_hotel`) REFERENCES `hotels` (`hotel_id`) ON DELETE CASCADE;
ALTER TABLE `regions`
ADD CONSTRAINT `regions_ibfk_1` FOREIGN KEY (`belong_country`) REFERENCES `countries` (`cuntry_id`) ON DELETE CASCADE;
ALTER TABLE `regions_activity_offers`
ADD CONSTRAINT `regions_activity_offers_ibfk_2` FOREIGN KEY (`belong_activity`) REFERENCES `activities` (`activity_id`) ON DELETE CASCADE,
ADD CONSTRAINT `regions_activity_offers_ibfk_1` FOREIGN KEY (`belong_region`) REFERENCES `regions` (`region_id`) ON DELETE CASCADE;
ALTER TABLE `users_favourite_activities`
ADD CONSTRAINT `users_favourite_activities_ibfk_1` FOREIGN KEY (`belong_user`) REFERENCES `users` (`user_id`) ON DELETE CASCADE,
ADD CONSTRAINT `users_favourite_activities_ibfk_2` FOREIGN KEY (`belong_activity`) REFERENCES `activities` (`activity_id`) ON DELETE CASCADE;
The question is: how to best add a "user activity log" feature which stores the activities a user has taken part to? Note that both regions and hotels can have activities, and I need to be able to tell whether that activity has taken place in a region or in a hotel. Referential integrity should be guaranteed.
Present a query (it should use JOIN shouldn't it?) which lists all users and their activities along with the hotel id or region id. (the one which is not applicable can be NULL if required).
Simple solutions are better - so preferably without stored procedures or anything which digs too much in mysql-specific features.
Your database is not normalized - and the way you've done it looks like a poster-child for why normalization is a good idea.
hotels.average_rating?
WTF?
While it can make sense to denormalize your data - this is not how to do it. Think about what you need to do when a user submits a hotel rating - you need to recalculate the value based on all the ratings submitted. If instead you held a sum_of_ratings (or even retained the current average) and a number of ratings then you could calculate the new values based on the hotel record and the new rating without having to look at the other ratings.
I have tried adding a foreign key like this...
ALTER TABLE OrderLineItem
ADD CONSTRAINT
FK_OrderLineItem_ShippingType_name FOREIGN KEY
(shippingType)
REFERENCES ShippingType(name);
Or like this in Mysql 5.5...
alter table OrderLineItem add foreign key
FK_OrderLineItem_ShippingType (shippingType) references ShippingType(name);
Every time I see the following error.
[2011-11-18 15:07:04] [HY000][150] Create table
'realtorprint_dev_dev/#sql-7d0_80' with foreign key constraint failed.
There is no index in the referenced table where the referenced columns
appear as the first columns.
[2011-11-18 15:07:04] [HY000][1005] Can't create table
'realtorprint_dev_dev.#sql-7d0_80' (errno: 150)
Both OrderLineItem.shippingType and ShippingType.name have a type of varchar(50) not null. ShippingType.name is the primaryKey of ShippingType.
Here is the result of show create table on ShippingType as well as OrderLineItem...
CREATE TABLE `shippingtype` (
`name` varchar(50) CHARACTER SET latin1 NOT NULL DEFAULT '',
`description` varchar(255) CHARACTER SET latin1 NOT NULL,
PRIMARY KEY (`name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `orderlineitem` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`description` varchar(255) CHARACTER SET latin1 NOT NULL,
`lineNumber` int(11) NOT NULL,
`quantity` int(11) NOT NULL,
`quantityMultiplier` int(11) NOT NULL,
`unitPrice` decimal(10,2) NOT NULL,
`order_id` bigint(20) NOT NULL,
`productDefinition_id` bigint(20) NOT NULL,
`mlsId` varchar(255) CHARACTER SET latin1 DEFAULT NULL,
`printProviderUnitCost` decimal(10,2) NOT NULL,
`shippingType` varchar(50) NOT NULL,
`address` varchar(255) DEFAULT NULL,
`zipPostal` varchar(255) NOT NULL,
`city` varchar(255) NOT NULL,
`stateProvince` varchar(255) NOT NULL,
`country` varchar(255) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `idx_OrderLineItem_productDefinition_id` (`productDefinition_id`),
KEY `idx_OrderLineItem_order_id` (`order_id`),
CONSTRAINT `FK_OrderLineItem_order_id` FOREIGN KEY (`order_id`) REFERENCES `userorder` (`id`),
CONSTRAINT `FK_OrderLineItem_productDefinition_id` FOREIGN KEY (`productDefinition_id`) REFERENCES `productdefinition` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=10029 DEFAULT CHARSET=utf8;
It is possible is that Mysql gives this bad error when the column types do not match exactly - check collation / size etc.
orderLineItem.shippingType has character set utf8, but ShippingType.name has character set latin1. These are not compatible for the purposes of foreign key references.
Data type mismatches or PK not declared properly on referenced based tables.