Best way to store users address into european database? - mysql

I would like to storing user's address (country-region-town) into a database. This database is the core of a european app. I have a table of countries and foreach country, I have two tables, one for regions and one for towns/cities.
So, what's the best way to storing user's address into database?
I could create different tables foreach country and rename them "users_italian", "users_french" with columns "idUsers" and "idTown" and I should connect them with the respective town table. It's simple but this mode does not convince me because there would be too many tables.
alternatively I could create a table "users_country" with "idUsers" and "idCountry" (foreign key) and I should memorize region and country into another table "users_address" with "idUsers", "region" and "town", but with string date type, example:
users(idUsers:1, email:useremail#mail.com, psw:secrethashedpsw, token:secrettoken)
country (idCountry:1, Country: "United Kingdom")
users_country (idUsers:1, idCountry:1(refer to United Kingdom))
users_address (idUsers:1, region:"England", town:"London", zip: SW1H 0TL (example))
Also this mode does not convince me because the database would not be normalized, but it's simple to realize it! and the query select it's simple too. I could create different tables about "users_region", "users_town" and "users_zip", but the storing with strings does not convince me.
Anyone can help me?

One table per country? NO!
Have a single users table. It would have
Plan A: address and either city+region+country.
Plan B: address plus id linking to (normalized) table of cities. Cities contains city+region+country.
Normalizing country, for example, adds complexity without adding any benefit.

Related

Should I use multiple databases for single project

I am working on a site which provides coupons for online shopping sites.
It provides discount coupons for shopping sites in India.
But now the client wants to provide coupons for USA stores also.
But offers available for Indian users are not useful for the USA users and vice versa.
Therefore there will be two versions of the site. One is for the Indian users and other is for the USA users.
But if a user from India searches for an offer which is not available in India but is available in the USA. Then it should appear in search results.
Now I am thinking of creating a new database for the USA users with exact same schema as that of the database for current users(Indian users).
But I would like to get advice from an expert.
In the long run you might want to add more countries so I would do it by adding a country table kind of thing and something like offer_valid for offerid country id which would make a single offer valid for one country or more.
Creating multiple databases would make the maintenance hectic.
Creating a separate database or a separate table (by adding _usa to table name) for that matter does not make sense.. because the same can be achieved by creating a mapping table which maps offers/coupons to the country/countries for which it is valid and is more scalable as well.
Here is what I suggest:
countries: id, name
coupons: id, name, discount
coupon_country_mapping: id, country_id, coupon_id, is_active

Many Bool columns in database table

I recently took over a website where people can register to help tutor kids. Part of the user's details is which areas they could work, represented by postal codes. The problem is, my predecessor designed the site such that in the database there is a Boolean column for every postal code. As such, the user table has almost 270 columns and can be quite slow at times (plus it's a nightmare to administer).
Most users select only a few postal codes so there is surely a better way to do it. I was thinking about a varchar that could save the selected areas comma separated, e.g. 6043,8811,1234
Any advice from somebody who's had the same problem?
both your predecessor's and your solution are... strange.
You should simply have a relationship table between user and localities (assuming you have a locality table, with a postalCode field and a surrogate key (id)).
UserLocality(userId int, localityId int)
so a locality could have many user, and a user could have many localities.
Coma separated fields is a really bad idea, when query time comes.
You should throw that entire idea out of your head and look into properly normalized data.
A possible solution to this problem would be a table for tutors, which has an id column to uniquely identify one tutor.
Then you would have a table for just Postal Codes (each with unique ids as well) and finally a tutor_availability table that creates one record of (t_id, pc_id) for each postal code a tutor wishes to offer their services, again with a unique id to avoid duplication risks in the case they can select the same location twice.

What is better way to specify location of user : 3 columns or one location varchar column in mysql?

I need some way to assign address to the user . Address consists of three values :
country
region
city
It is possible to create 3 columns for country, region and city.
But it is also possible to create one varchar column and separate country,region,city by comma.
Which approach is better if I need to query for user by country and/or region and/or city?
It is best practice to store the address in 3 separate columns. This makes it easier to search by one value or using and/or statements to query based off of several values.
Another option to keep your main table small (and fast for processing): if you won't need the region and country all the time, create separate tables for each, then you can use a JOIN only when you need to determine these values (you'll join the city back to a country and a country back to a region - aka continent). This falls under the category of Data Normalization. Good luck.

How should I design MS Access 2010 tables for road construction projects?

New to database design and admittedly over my head. Trying to create a small database that will allow me to find state highway construction project information along any given road. Relationships include:
One contract number to one project; One county to many projects; One road to many projects; One road to many counties and one county to many roads; One manager to many projects; One contractor to many projects; One contact list (phone, email) to one manager; One date each (bid, start, complete) to many projects.
Would be a small database, maybe 500 records total. There are only 6 counties. Right now I've broken roads down into 6 separate "roads by county" tables so while the route number may be the same in different counties each record will be unique because it's in a separate county table. Is this OK or is it better to keep one roads table and assign county values there? I created other tables listing the counties, contracts, contractors, managers, dates and project description. Just don't know what to do with them.
My purpose is to be able to search, mostly by road number and keyword, to find what projects are on what road at any given time. I'd also like to update this info via forms. The data will change frequently and it's just a little too unruly for a spreadsheet. I simply can't wrap my head around how to setup and relate the tables and individual records. Any thoughts would be phenomenally appreciated.
I imagine a database with a simple structure.
The relations many-to-many normally should and can be avoided.
Access doesn't have a direct implementation of this relations. You need to create a cross table between the two main tables.
Anyway I created a database for projects more complex than this so I tried to accomplish your request.
The "core" table is tblProjects that refers for details to other tables.
Since projects are related to roads, I use road as the main item and a road can have a list of counties. If you want to know how many projects are in a county it can be simply done with a query looking for all the roads that have that County_ID.
If you want to look up for project for one road, simply find the road_ID (e.g. using a combo-box to select it) and you can filter (query) the tblProjects by Road_ID.
tblManagers
*IDManager
LastName
FirstName
eMail
Phone
Mobile
tblContractors
*IDContractor
ContractorName
Reference
tblCounties
*IDCounty
CountyName
Road_ID
tblRoads
*IDRoad
RoadNum
RoadName
tblProjects
*IDProject
ContractNum
ProjectName
StartDate
EndDate
BidDate
Contractor_ID
Road_ID
Manager_ID
The fields with * are the Key Fields. They are in relations with the _ID corresponding fields (check referential integrity and cascade deletion when you create the relation).
Let me know

Database Normalization with user input

I develop a mysql database that will contain the country,city and occupation of each user.
While I can use a "country" table and then insert the id of the country into the user table, I still have to look for the perfect method for the other two tables.
The problem is that the city and occupation of each user are taken from an input field, meaning that users can type "NYC" or "New York" or "New York City" and millions of other combinations for each town, for example.
Is it a good idea to disregard this issue, create an own "town" table containing all the towns inserted by users and then put the id of the town entry into the user table or would it be more appropriate to use a VARCHAR column "town" in the user table and not normalize the database concerning this relation?
I want to display the data from the three tables on user profile pages.
I am concerned about normalization because I don't want to have too much redundant data in my database because it consumes a lot of space and the queries will be slower if I use a varchar index instead of an integer index for example (as far as I know):
Thanks
We had this problem. Our solution was to collect the various synonyms and typo-containing versions that people use and explicitly map them to a known canonical city name. This allowed to correctly guess the name from user input in 99% of cases.
For the remaining 1%, we created a new city entry and marked it as a non-canonical. Periodically we looked through non-canonical entries. For recognizable known cities, we remapped the non-canonical entry to the canonical (updating FKs of linked records and adding a synonym). For a genuinely new city name we didn't know about we kept the created entry as canonical.
So we had something like this:
table city(
id integer primary key,
name varchar not null, -- the canonical name
...
);
table city_synonym(
name varchar primary key, -- we want unique index
city_id integer foreign key references(city.id)
);
Usually data normalization helps you to work with data and keep it simple. If normalized schema not fit your needs you can use denormalized data as well. So it depends on queries you want to use.
There is no good solution to group cities without creating separate table where you will keep all names for each city within single id. So it will be good to have 3 tables then: user(user_id, city_id), city (city_id, correct name), city_alias(alias_id, city_id, name).
It would be better to store the data in a normalized design, containing the actual, government recognized city names.
#Varela's suggestion of an 'alias' for the city would probably work well in this situation. But you have to return a message along the lines of "You typed in 'Now Yerk'. Did you perhaps mean 'New York'?". Actually, you want to get these kinds of corrections regardless...
Of course, what you should probably actually store isn't the city, but the postal/zip code. Table design is along these lines:
State:
Id State
============
AL Alabama
NY New York
City:
Id State_Id City
========================
1 NY New York
2 NY Buffalo
Zip_Code:
Id Code City_Id
=========================
1 00001-0001 1
And then store a reference to Zip_Code.Id whenever you have an address. You want to know exactly which zip code a user has (claimed) to be a part of. Reasons include:
Taxes for retail (regardless of how Amazon plays out).
Addresses for delivery (There is a Bellevue in both Washington and New York, for example. Zip codes are different).
Social mapping. If you store it as 'user input' cities, you will not be able to (easily) analyze the data to find out things like which users live near each other, much less in the same city.
There are a number of other things that can be done about address verification, including geo-location, but this is a basic design that should help you in most of your needs (and prevent most of the possible 'invalid' anomalies).