I'm really new to databases so please bear with me.
I have a website where people can go to request tickets to an upcoming concert. Users can request tickets for either New York or Dallas. Similarly, for each of those locales, they can request either a VIP ticket or a regular ticket.
I need a database to keep track of how many people have requested each type of ticket (VIP and NY or VIP and Dallas or Regular and NY or Regular and Dallas). This way, I won't run out of tickets.
What schema should I use for this database? Should I have one row and then 4 columns (VIP&NY, VIP&Dallas, Regular&NY and Regular&Dallas)? The problem with this is it doesn't seem very flexible, thus I'm not sure if it's good design.
You should have one column containing a quantity, a column that specifies the type (VIP), and another that specifies the city.
To make it flexible you would do:
Table:
location
Columns:
location_id integer
description varchar
Table
type
Columns:
type_id integer
description varchar
table
purchases
columns:
purchase_id integer
type_id integer
location_id integer
This way you can add more cities, more types and you allways insert them in purchases.
When you want to know how many you sold you count them
What you want to do is have one table with cities and one table with ticket types.
Then you create a weak association with [city, ticket type, number of tickets].
That table will have 2 foreign keys, therefore "weak".
But this enables you to add or remove cities etc. And you can add a table for concerts as well and your weak table you will have another foreign key "concert".
I think this is the most correct way to do it.
CREATE TABLE `tickets` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`locale` varchar(45) NOT NULL,
`ticket_type` varchar(45) NOT NULL
}
This is a simple representation of your table. Ideally you would have separate tables for locale and type. And your table would look like this:
CREATE TABLE `tickets` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`locale_id` int(11) NOT NULL,
`ticket_type_id` int(11) NOT NULL
}
Related
I am trying to design a database based on the following information:
The landlord records the following data about each property:
-Eircode
-Capacity of property i.e. number of tenants it can hold
-Number of tenants currently renting this property
-Cost of rental per tenant per calendar month
The landlord stores the following information about each tenant:
-Name
-Email
-Phone number
What am I confused about is the "Cost Of Rental Per tenant" row, in which table to place and how to make the connection. Any help would be greatly appreciate it.
The following is what I got so far:
CREATE TABLE property (
Eircode int(11) NOT NULL AUTO_INCREMENT PRIMARY KEY,
MaxCapacity int(10) NOT NULL
NumberOfTenants int(10) NOT NULL
CostOfRental int(10) NOT NULL
);
CREATE TABLE tenant (
tenantID int(11) NOT NULL AUTO_INCREMENT PRIMARY KEY,
tenantName varchar(30) NOT NULL
tenantEmail varchar(30) NOT NULL
tenantPhone varchar(30) NOT NULL
);
As I understand your structure you have a table called tennant, wich holds information about tenants. If the payment is a property of the tenant (the amount this indivual tenant has to pay) you should add that property to that table.
Alternatively you could say the rent is for the whole property, and these costs are shared equally by each tenant. That way you would compute that outside the database.
Also I would not set the attribute NOT NULL to each value. Maybe you do not have an email address, therefor you may want to add a value there.
To connect the information you should set a table to make the connection. This contains of two columns (ID_property , ID_tenant)
Hope this will help you at least a bit.
I have a question about tables and relations tables ...
Actually, I have these 3 tables
CREATE TABLE USER (
ID int(11) NOT NULL AUTO_INCREMENT,
NAME varchar(14) DEFAULT NULL
);
CREATE TABLE COUNTRY (
ID int(11) NOT NULL AUTO_INCREMENT,
COUNTRY_NAME varchar(14) DEFAULT NULL
);
CREATE TABLE USER_COUNTRY_REL (
ID int(11) NOT NULL AUTO_INCREMENT,
ID_USER int(11) NOT NULL,
ID_COUNTRY int(11) NOT NULL,
);
Ok, so now, 1 user can have one or more country, so, several entries in the table USER_COUNTRY_REL for ONE user.
But, my table USER contains almost 130.000 entries ...
Even for 1 country by user, it's almost 10Mo for the USER_COUNTRY_REL table.
And I have several related tables in this style ...
My question is, is it the fastest, better way to do?
This would not be better to put directly in the USER table, COUNTRY field that contains the different ID (like this: "2, 6, ...")?
Thanks guys ;)
The way you have it is the most optimal as far as time constraints go. Sure, it takes up more space, but that's part of space-time tradeoff - If you want to be faster, you use more space; if you want to use less space, it will run slower (on average).
Also, think of the future. Right now, you're probably selecting the countries for each user, but just wait. Thanks to the magic of scope creep, your application will one day need to select all the users in a given country, at which point scanning each user's "COUNTRY" field to find matches will be incredibly slow, as opposed to just going backwards through the USER_COUNTRY_REL table like you could do now.
In general, for a 1-to-1 or 1-to-many correlation, you can link by foreign key. For a many-to-many correlation, you want to have a relation table in between the two. This scenario is a many-to-many relationship, as each user has multiple countries, and each country has multiple users.
Why not try like this: Create table country first
CREATE TABLE COUNTRY (
CID int(11) NOT NULL AUTO_INCREMENT,
COUNTRY_NAME varchar(14) DEFAULT NULL
);
Then the table user:
CREATE TABLE USER (
ID int(11) NOT NULL AUTO_INCREMENT,
NAME varchar(14) DEFAULT NULL,
CID Foreign Key References CID inCountry
);
just Create a Foreign Key relation between them.
If you try to put this as explicit relation , there will lot of redundancy data.
This is the better approach. You can also make that Foreign Key as index . So that the databse retrieval becomes fast during search operations.
hope this helps..
Note : Not sure about the exact syntax of the foreign key
I am confused about the correct/most efficient way to place data in my dababase table when there is a OneToOne relationship.
For example, I have a users table.
I now wish for each user to be able to state his current country location.
i then want to be able to search the datatable for users by current location.
The way that I have done this is to create 3 separate tables. i.e
table one - users : just contains the user information:
CREATE TABLE users(
id MEDIUMINT UNSIGNED NOT NULL AUTO_INCREMENT,
firstName VARCHAR(30) NOT NULL,
lastName VARCHAR(40) NOT NULL,
);
Table two country list: a list of countries and respective Ids for each country
PHP Code:
CREATE TABLE countrylist(
country_id MEDIUMINT UNSIGNED NOT NULL,
country VARCHAR(60) NOT NULL,
INDEX country_id ( country_id, country ),
INDEX countrylist (country, country_id ),
UNIQUE KEY (country)
);
Table 3; contains the userId and the countryId he lives in:
PHP Code:
CREATE TABLE user_countrylocation(
country_id VARCHAR(60) NOT NULL,
id MEDIUMINT UNSIGNED NOT NULL,
INDEX country_id (country_id, id ),
INDEX user_id (id, country_id )
);
Alternatively, should I place the countryId in the users table and completely get rid of the user_countrylocation. i.e in each user column, I will place a country_id for the country he lives in.
The problem is that I have over 20 similar tables as above that give details on users; i.e languages spoken, age-group, nationality etc.
My concerns is that if I place this unique information in each users column in the user table, then what would be the most efficient way to search the database: that is why I opted for the style above.
So, I really request for some advice on the most efficient/correct way to plan the database.
If you are going to have a huge data then you should keep the same approach and use the following method to keep the one to one constraint satisfied
if you don't have a huge data then you should keep the look up tables like country and use the reference for user in a column. but then you may need to allow them nulls that is make such optional information columns nullable.
The most efficient and exactly correct way is to first delete the data from the third table "user_countrylocation" for the user to be updated. Then insert the new location for the user. don't forget to use transaction.
your table 3 should have
country_id MEDIUMINT UNSIGNED NOT NULL,
instead of
country_id VARCHAR(60) NOT NULL,
and also change tyhe column name from id to user_id in all tables.
if you are using a stored procedure it would be like
create procedure sp_UpdateUserCurrentCountry (
#userID MEDIUMINT UNSIGNED,
#CountryID MEDIUMINT UNSIGNED)
begin
as
delete from user_countrylocation
where user_id = #userID
insert into user_countrylocation
(
country_id,
user_id
)
values
(
#CountryID,
#userID
)
END
One to One relations are usually mapped via Foreign Keys linking the two tables together. A third mapping table is only required for Many to Many relationships. So, you should ideally have a Foreign Key Country_ID in your Users table.
Your SELECT query would then look like
SELECT * FROM Users
WHERE Country_ID = (
SELECT Country_ID FROM Countries
WHERE Country_Name = 'USA'
);
I am having an issue that involves a differentiation between whether a status update belongs to a user or a company. Let me explain: Individuals can post statuses as a user or as a company. A user can be a member/owner of a company and switch to a company in the dashboard much like Facebook. The problem is: how will we set in the database whether a status was posted by a company or by a user?
My solution was to have a company column that was a Boolean variable and when we query for each status to display we check if it was from a company. If so then we grab the company_id and look up the name and other relevant information in the database and display it on the site. Does this sound like the right approach? Additionally, does the schema below look correct?
**Company**
id int(11)
name varchar (255)
**Company_members**
company_id int(11) FK_Company
user_id int(11) FK_Users
owner BOOLEAN
**Users**
id int(11)
name varchar (255)
**Status**
id
date DATETIME
user_id FK_Users
company_id FK_Company
company BOOLEAN
Your schema looks good, but the company boolean in the Status table seems redundant. You can just set the company_id to NULL when the status is for an individual's account, and then query SELECT * from Status WHERE company_id IS NULL to get individuals' statuses, and SELECT * FROM Status WHERE company_id IS NOT NULL to get companies' statuses.
Use the Party Model. You need to use table inheritance. Single Table inheritance is simpler and faster but may use nulls.
create table party_type (
id int primary key,
description text not null unique
);
insert into party_type values
(1, 'Individual'),
(2, 'Organization');
create table party (
id serial primary key,
type int not null references party_type(id),
name text not null
);
create table status_update(
id serial primary key,
date datetime,
party_id not null references party(id)
);
(syntax is postgres but you should be able to translate to mysql easily)
I'm working on an application which tracks prices for certain items.
Each price has a reference to an item, a business that sells that item, and the location the item is being sold at. Now, normally, this would do just fine:
CREATE TABLE `price` (
`priceId` INT UNSIGNED NOT NULL AUTO_INCREMENT, -- PK
`businessId` INT UNSIGNED NOT NULL,
`itemId` INT UNSIGNED NOT NULL,
`locationId` INT UNSIGNED NOT NULL,
`figure` DECIMAL(19,2) UNSIGNED NOT NULL,
-- ...
)
But I have the following problem:
The application logic is such that one item at one business at one location can have multiple prices (at this point it's not really important why), and one of those prices can be an official price - an item doesn't have to have an official price, but if it does, there can be only one.
The question is; how to model this to ensure data integrity?
My initial idea was to create an additional table:
CREATE TABLE `official_price` (
`priceId` INT UNSIGNED NOT NULL -- PK + FK (references price.priceId),
-- ...
)
This table would hold priceId:s for prices that are official, and the PK/UNIQUE constraint would take care of the 'one-or-none' constraint.
This seems like a workable solution, but I'm still wondering if there's a better way to handle this situation?
You can use this dirty hack:
add a field is_official to price table, null as a value is possible in it
create an unique composite index priceId + is_official
for the official prices put 1 to is_official
for not official left it to be null
You could make the price table hold only official prices (with the figure possibly null), put a unique constraint on (businessId, itemId, locationId), and add another table of auxiliary prices referencing priceId.