SQL messages that can be read by specified users - sql

Task:
At present, the database knows two types of messages:
Messages that a user posts and that are public for anyone and everyone to read
Messages that a user posts and that are non-public.
These messages can only be read by users that the posting user has marked as friends.
In this step, you should add a third type of message. This third type of message should be readable by specified recipients only.
This means the database needs to provide the following:
A way of distinguishing between the three types of messages. This involves a change to the Message table.
A way of specifying who the recipients of a particular message are. This will probably require an additional table.
Your job is to implement the necessary changes and additional table for this purpose and any keys and foreign key
relationships required.
here are two existing tables witch relate to the task(copies from my db).
User table
CREATE TABLE IF NOT EXISTS `User` (
`user_id` int(10) unsigned NOT NULL auto_increment,
`given_name` varchar(60) default NULL,
`surname` varchar(60) default NULL,
`address` varchar(255) default NULL,
`city_id` int(10) unsigned NOT NULL,
`date_of_birth` datetime default NULL,
`email` varchar(80) default NULL,
PRIMARY KEY (`user_id`),
KEY `ix_user_surname` (`surname`),
KEY `ix_user_given_name` (`given_name`),
KEY `ix_user_name` (`given_name`,`surname`),
KEY `ix_user_date_of_birth` (`date_of_birth`),
KEY `ix_user_email` (`email`),
KEY `ix_user_city_id` (`city_id`)
) ENGINE=InnoDB
Message table
CREATE TABLE IF NOT EXISTS `Message` (
`message_id` int(10) unsigned NOT NULL auto_increment,
`owner_id` int(10) unsigned default NULL,
`subject` varchar(255) default NULL,
`body` text,
`posted` datetime default NULL,
`is_public` tinyint(4) default '0',
PRIMARY KEY (`message_id`),
KEY `ix_message_owner_id` (`owner_id`)
) ENGINE=InnoDB

Ok, so is_public give you the ability to distinguish between two types (e.g. is_public = '0' means private, and is_public = '1' means public). But now you have a new concept of specified receipts, so the yes/no model won't work anymore b/c you have 3 types. Usually in this situation you can switch to a flag or type column.
So maybe make a message_type column that is one of 'PUBLIC', 'PRIVATE', 'SPECIFIED' or something like that.
After that it sounds like you need at least two more tables. Users must be able to specify friends and users must be able to specify users to receive particular messages.

Related

mysql duplicate key error during restoration through mysqldump data

I have a mysql database which is having one table for geo location and saves latitude and longitude values of users. The fields are as followed
TABLE USER_LOCATION (
LATITUDE float NOT NULL DEFAULT '0',
LONGITUDE float NOT NULL DEFAULT '0',
STATE varchar(50) NOT NULL,
COUNTRY varchar(255) DEFAULT NULL,
ADDRESS varchar(255) DEFAULT NULL,
CITY varchar(45) DEFAULT NULL,
DISTRICT varchar(45) DEFAULT NULL,
PRIMARY KEY (LATITUDE,LONGITUDE),
KEY latlong (LATITUDE,LONGITUDE),
KEY longlat (LONGITUDE,LATITUDE)
) ENGINE=InnoDB DEFAULT CHARSET=latin1
Problem 1:- Some time fields get duplicate value and the insertion happens successfully.
Problem 2:- If I have taken mysqldump of data and try to restore with the same duplicate rows , then I receive duplicate PRIMARY KEY error like this.
ERROR 1062 (23000): Duplicate entry '17.4273-78.3316' for key 'PRIMARY'
Now I am not able to understand that why the first problem happens and why this is detected in problem 2.

SQL Relationship Cardinality in Logical Design

I have the following issue. We are currently working on a system for a shuttle service company. Now, part of the entities in the database for this system include numerous lookup tables (such as vehicle_type, employee_status, etc), as well as some other tables, such as vehicle and vehicle_service log.
Now the issue we as a team are having is that we cannot agree on what the logical relationship cardinalities between entities should be. The two main problem relationships include the tables defined as follows:
CREATE TABLE IF NOT EXISTS `user_type` (
`type_id` tinyint(4) NOT NULL AUTO_INCREMENT,
`description` varchar(200) NOT NULL,
PRIMARY KEY (`type_id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 COMMENT='Store the user types - employee
or consultant' AUTO_INCREMENT=1 ;
which is linked to
CREATE TABLE IF NOT EXISTS `user` (
`user_id` int(11) NOT NULL AUTO_INCREMENT,
`username` varchar(100) NOT NULL,
`password` varchar(100) NOT NULL,
`user_type` tinyint(4) NOT NULL,
PRIMARY KEY (`user_id`),
KEY `user_type` (`user_type`),
KEY `username` (`username`),
KEY `login` (`username`,`password`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 COMMENT='Table used when logging in
to check access level, type of user, etc. ' AUTO_INCREMENT=1 ;
The user table includes other irrelevant data. So the issue here is that I say (because MySQL Workbench reverse engineered it that way and it makes more sense) that the relationship should be 1-many, while another team member says that it should be 0-many (because some records may exist in the user_type table that aren't used in the user table)
The other table relationship we are having words about are defined as follows:
CREATE TABLE IF NOT EXISTS `vehicle` (
`vehicle_id` int(11) NOT NULL AUTO_INCREMENT,
`registration_number` varchar(10) NOT NULL,
PRIMARY KEY (`vehicle_id`),
UNIQUE KEY `registration_number` (`registration_number`),
) ENGINE=InnoDB DEFAULT CHARSET=latin1 COMMENT='Actual vehicle information'
AUTO_INCREMENT=1 ;
Again, with some other columns not relative to the question. This links with
CREATE TABLE IF NOT EXISTS `service_log` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`vehicle_id` int(11) NOT NULL,
`description` text NOT NULL,
`date` date NOT NULL,
`cost` double NOT NULL,
PRIMARY KEY (`id`),
KEY `vehicle_id` (`vehicle_id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 COMMENT='Store records of all services
to vehicles' AUTO_INCREMENT=1 ;
Should this be 1-many or 0-many because a vehicle may not yet go in for a service? According to me it should be 1-many, but I don't know if this works logically.
We are all very confused about this whole logical modelling thing, so any help would be much appreciated!
I figured it would be easier for me to create the DB first and then reverse engineer it to a physical model, but never though about logical.
Zero to many if it is optional. Say for example a Sales Rep would have a zero or many customer. Why is that? Because if there is a new sales rep then it would mean he/she has no customer to begin with unless of course he/she assume the accounts of a resigned Sales Rep.
On the other hand one or many is mandatory. For example a an Order which has order date and customer who ordered should have at least one record on Order Detail table. Let's say a customer ordered a tablet last 04/22/2013 then he/she would have:
Order table
----------------------------------------
Orderid. OrderDate. Customermnum
----------------------------------------
1. 04/22/2013 101
Order detail table
----------------------------------------
Orderid. Productid. Qty. quotedprice
----------------------------------------
1. T101 1 500
So, in your case User to UserType is 1 to 0 or many beacause a user type may have not been used by any user yet.
Now, vehicle to service It is also 1 to 0 or many since a vehicle may not necessarily have a service done yet.

creating friend graph

I want to create a friend list for my website which is supposed to be stored in a database table, following is the table structure I think should best serve the purpose.
CREATE TABLE `sdt_friend_graph` (
`user` INT(11) NOT NULL,
`friend` INT(11) NOT NULL,
`status` ENUM('requested','accepted') COLLATE utf8_unicode_ci DEFAULT NULL,
`requested_on` DATETIME DEFAULT NULL,
`accepted_on` DATETIME DEFAULT NULL,
PRIMARY KEY (`user`,`friend`)
)
just want to find out if my approach is ok, or is there any better way to do this to make it more efficient, I'm open to suggestions.
Regards,
your table structure looks fine, i would just add user as an AUTO_INCREMENT field and change the name to friendid... just for semantics.

Specify sorting criteria manually for a set of records of a many-to-many relationship

I am designing a many-to-many relationship between two models: Cell and Isolator:
CREATE TABLE `isolator` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`name` varchar(127) NOT NULL,
`surname` varchar(127) NOT NULL,
PRIMARY KEY (`id`),
);
CREATE TABLE `cell` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`name` varchar(127) NOT NULL,
`gen` varchar(127) NOT NULL,
PRIMARY KEY (`id`),
);
CREATE TABLE `cell_isolators` (
`cell_id` bigint(20) NOT NULL DEFAULT '0',
`isolator_id` bigint(20) NOT NULL DEFAULT '0',
PRIMARY KEY (`cell_id`,`isolator_id`),
CONSTRAINT `cell_isolator_id` FOREIGN KEY (`isolator_id`) REFERENCES `isolator` (`id`),
CONSTRAINT `isolator_cell_id` FOREIGN KEY (`cell_id`) REFERENCES `cell` (`id`) ON DELETE CASCADE
);
The client has asked me the possibility of specifying the order on which the list of isolators for a cell is shown, since it's important for publication purposes.
What is the best approach to model that? I was thinking on adding a third field to the many-to-many relation (e.g. sort_order), but I would like to know if there are other alternatives.
Thanks!
The only way to do that in the general case is to add a column to "cell_isolators".
The data type is application-dependent to a certain extent. I've seen this done with columns as integers, floats or decimals, and alphanumerics (varchar(n)).
Populating and maintaining it can be troublesome, though. That doesn't have anything to do with the database design; it's just painful to maintain the sort order for more than a few rows, especially if there are regular inserts to the table and changes to the sort order. Fortunately, that job usually falls to the user interface, not to the dbms.

SQL problem if two diffrent author have same name in books database

Just wanted to know what would happen if in my book database i had two different authors which have the same name. How could i redesign my database to sort this problem out? Do i have to assign primary and secondary keys or something? By the way this question is related to my previous one.
An AUTHORS table would help your book database - you could store the author info once, but associate it with multiple books:
DROP TABLE IF EXISTS `example`.`authors`;
CREATE TABLE `example`.`authors` (
`author_id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`firstname` varchar(45) NOT NULL,
`lastname` varchar(45) NOT NULL,
PRIMARY KEY (`author_id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
Books can have multiple authors, so you'd need a many-to-many table to relate authors to books:
DROP TABLE IF EXISTS `example`.`book_authors_map`;
CREATE TABLE `example`.`book_authors_map` (
`book_id` int(10) unsigned NOT NULL,
`author_id` int(10) unsigned NOT NULL,
PRIMARY KEY (`book_id`,`author_id`),
KEY `FK_authors` (`author_id`),
CONSTRAINT `FK_books` FOREIGN KEY (`book_id`) REFERENCES `books` (`book_id`),
CONSTRAINT `FK_authors` FOREIGN KEY (`author_id`) REFERENCES `authors` (`author_id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
You should almost always use your own in-house ID system, even if it's never displayed to your users. In your database each book will have it's own 'id' attribute, which you can just auto-increment by 1 each time.
The reason for doing this, other than the example in your question, is that even if you use a seemingly unique identifier (like an ISBN), this standard could (and has) change at some point in time, leaving you with a lot of work to do to update your database.
If you have two different authors with the exact same name, each author should have some sort of unique ID to differntiate them, either a GUID or an autonumber.
Use natural keys where they exist - in this case ISBN numbers