SQL - Contacts, Companies DB Design - sql

Im working on a db to manage customer data for a small company.The customers are companies and institutions (schools..etc) and of course people/contacts. There will be a lot more scope added in time, but right now I'm looking for any input on the core design itself and if there's anything I'm missing here that could cause issues down the road. The image doesn't include the additional lookup tables for items like; country, teltype..etc. I'm kinda worried that I've over-normalised it and it is going to make the queries much more complicated in the long-term. Any input appreciated.
Update - 13/12/2016
I have since created a superclass in my structure called entity, which helps me merge all 3 into one as such. I'm still working on the rest as it has grown quite a lot today, so again any input is appreciated.

The first impression I get looking at the diagram is that you have over-normalised the data (unless that was your aim).
Consider the Company <-> Telephone relationship you have created:-
Creating a relationship like this reads:
A Company can have one to many Telephone Numbers
A Telephone Number can belong to one to many Companies
Evaluating this for a minute; is it likely that a telephone number is shared by more than one Company in your structure? (real-world suggests it wouldn't)
Expanding upon this, I believe the main reason you may have headed down this course would be to allow the same telephone number to apply to one or many contacts as well as a business?
Personally, in my experience, I would suggest a duplication of data (telephone number) maybe easier to maintain and manage from a development perspective. This will make you data structure and application logic less complex, and should make searching less taxing on the system.
However, it will also mean you could end up with stale data, for example, if all of your contacts used the company phone number and the company number was updated, all of the contacts data would now need updating too.
One way round that from an application perspective would be to display the company number with a company contact, then you would not need to duplicate data.
Here is an example of a de-normalised view of this relationship:
You could also apply this to email addresses, where the same concept applies.

Do you need to have bridge tables for telephone, email, and location? If there is no need to have multiple sites, e-mails, or telephone numbers; you can add the attributes to the primary entity.

Related

When to use one to many vs many to many in right situation?

i quite confuse when, or not to use one to many vs many to many. ex, user roles. in such situation many to many have advantage in reduce data size cause it just point to integer, maybe it save 1-10bytes each row, ex, senior developer char with id 7, it consume 2 bytes in smallint, instead 16 bytes. but, it makes bloat table. if such situation use many to many. why one to many should exists if many to many have the advantage? is it not always good to many to many?
Users table
id
username
password
Users_Roles table
user_id
role
Versus
Users table
Users_Roles table
user_id
role_id
Roles table
id
role
You're prematurely optimizing. A few integers here and there is unlikely to impact your data size nor your performance. If it does, the schema can be changed later, but usually there is much bigger bloat to be concerned with.
One-to-many vs many-to-many is not an optimizing issue. It's about the relationship between the tables.
If one and only one user can have a role, use one-to-many.
If many users can have the same role, use many-to-many.
For example, if you have an admin role and there can ever only be one admin user, use one-to-many. If there can be many admins, use many-to-many. You have to decide what the relationship is between users and roles.
Note: Use bigints for ids. 4 billion might seem like a lot, but it comes up fast and one of the worst things that can happen is to run out of IDs.
This is a data modeling question, and it's answer comes out of and is dictated by the analysis of the relationships of the entities involved. You have identified 2 entities you want to store data about, users and roles. Now describe their relationship in spoken language terms, looking at the relationship from both directions.
Can a user have more than one role? Can a role be held by more than one user? If the answer to both is yes, than it's a many to many relationship. Take the primary keys of both entities and bring them together as the composite primary key of an associative table. It may not have any attribute unless there is data about the relationship of a user/role itself that needs to be captured.
However, what if you are modeling entities of invoices and line items? Can an invoice have more than one line item? Yes. Can an instance of a line item on an invoice belong to more than one invoice? No (note I'm modeling a line item, not a product or part number as a line item could include special pricing for this invoice, color, logo, etc). So this is clearly a one to many relationship in the direction of one invoice can have many line items.
For more information, do some searching on data modeling, it will be a huge help in your database design efforts and you will end up with a better design for more efficient queries by designing the database correctly.
Looks like Schwern and I were typing at the same time :-)

Two shops and sync clients between them with passwords

Is this possible to sync customers between two seperate prestashop 1.7 shops? I dont want to use multistore option..is there a module for that or maybe some database operations?
Customers are stored in a single database table (ps_customer) , so if you are able to write a synchronization routine between the two database tables you should be able to achieve that.
There are several additional considerations though :
Both stores must have the same "cookie_key" set in the site parameters for same passwords to be validated in both shops, so you'll have to start with at least one empty store.
Customers have different relationships to databases based on their id_customer auto_increment values (addresses, orders, third party modules etc.), so you'll need to know what you're doing and make sure the two shops can't have conflicts between customer ids (IE: you can start one of the two shops with a very high id_customer..) - Also not sure if you need to handle also addresses synchronzation.. This would add some complexity.
I hope I've given you some good starting points - but I would stick with native "multishop" PS feature for that - It would be far easier despite still having a lot of bugs :)

New to Microservices - refactoring a monolith "Marketplace" database

I am new to microservices and have been struggling to wrap my brain around it. On the surface they sound like a good idea, but from a practical standpoint, I can't break away from my centralized database background. For an example, I have this real-world Marketplace example that I cannot figure out if microservices would help or hurt. This site was working well until the PO asked for "Private Products." Now it is fragile and slow so I need to do a major refactor. A good time to implement microservices. I feel like many systems have this type of coupling, so that deconstructing this example would be very instructive.
Current State
This is a b2b marketplace where users belong to companies that are buying products from each other. Currently, there exists a monolithic database: User, Company, Catalog, Product, and Order. (This is a simplification, the actual scenario is much more complicated, users have roles, orders have header/detail, products have inventories, etc.)
Users belong to Companies
Companies have a Catalog of their Products
Companies have Orders for Products from other Companies
So far so good. I could see breaking the app into microservices on the major entity boundaries.
New Requirement
Unfortunately for my architectural aspirations, the product owner wants more features. In this case: Private Products.
Products are Public or Private
Companies send time-bound Invitations to Products or Catalogs to Users of other Companies
This seemingly simple request all the suddenly complicated everything.
Use Case - User displays a list of products
For example, listing or searching products was once just a simple case of asking the Products to list/search themselves. It is one of the top run queries on the system. Unfortunately, now what was a simple use case just got messy.
A User should be able to see all public Products (easy)
A User should be able to see all their own Company's private Products (not horrible)
A User can see any Product that their Company has Ordered in the past regardless of privacy (Uh oh, now the product needs to know about the User Company's Order history)
A User can see any private Product for which they have an active Invitation (Uh oh, now the product needs to know about the User's Product or Catalog Invitations which are time dependent)
Initial Monolithic Approach
This can be solved at the database level, but the SQL joins basically ALL of the tables together (and not just master data tables, all the transactions as well.) While it is a lot slower than before, since a DBMS is designed for big joins it seems like the appropriate tool. So I can start working on optimizing the query. However, as I said, for this and other reasons the system is feeling fragile.
Initial Design Thoughts... and ultimately my questions
So considering a Microservices architecture as a potential new direction, I began to think about how to start. Data redundancy seems necessary. Since, if I translate my major entities into services, asking to get a list of products without data redundancy would just have all of the services calling each other and a big slow mess.
Starting with a the idea of carving out "Product and Catalog" as its own microservice. Since Catalogs are just collections of Products, they seem to belong together - I'll just call the whole thing the "Product Service". This service would have an API for managing both products and catalogs and, most importantly, to search and list them.
As a separate service, to perform a Product search would require a lot of redundant data as it would have to subscribe to any event that affected product privacy, such as:
Listen for Orders and keep at least a summary of the relationship between purchased Products and Purchasing Companies
Listen to Invitations and maintain a list of active User/Product/Time relationships
Listen to User and Company events to maintain a User to Company relationship
I begin to worry about keeping it all synchronized.
In the end, a Product Service would have a large part of the current schema replicated. So I begin to think, maybe Microservices won't work for this situation. Or am I being melodramatic and the schema will be simpler enough to be more managable and faster so it is worth it?
Overall, am I thinking about this whole approach properly? Is this how microservice based designs are intended to be thought through? If not, can somebody give me a push in a different direction?
Try splitting your system into services over and over until it makes sense. Use your gut feeling. Read more books, articles, forums where other people describing how they did it.
You've mentioned that there is no point of splitting ProductService into Product and ProductSearch - fair enough, try to implement it like that. If you will end up with a pretty complicated schema for some reason or with performance bottlenecks - it's a good sign to continue splitting further. If not - it is fine like that for your specific domain.
Not all product services made equal. In some situations, you have to be able to create millions or even billions of products per day. In this situation, it is most likely that you should consider separating product catalogue and product search. The reason is performance: to make search perform faster (indexing) you have to slow down inserts. These are two mutually exclusive goals that are hard to reach without separating data into different microservices (which will lead to data duplication as well).

Database Design - Linking two users

I need some help with some database design. I am a FE developer by trade and have only dealt with very basic DBs. I am just starting to branch out into more "advanced" web apps and would like some pointers in the right direction for the schema.
What I am looking for is an account system that can basically link two accounts. I will give you the scenario I had imagined off the top of my head.
A user signs up in a regular way, just providing name, email, password for simplicity of this question. After they have signed up, the user can then link their account to another user by entering the others email and having it accepted by the other user.
Once this link has been created, the two users can CRUD tasks together.
The bit I am struggling with is how to create the link between the two users. I obviously have my users table.
USERS:
id
name
email
password
Now, I believe I need to create another table that holds the two linked accounts, that has its own unique ID that we can use to CRUD tasks. Something like:
LINKED_USERS:
id
user1id
user2id
verified
TASKS
id
lu_id (FK, Linked_Users id)
// Any other fields for the two combined here.
Is this correct? If so, how would I setup the relationships between the users table and the linked_users table? This is the bit that is confusing me because I need the relationship to reference two users IDs. Say I wanted to display user1id and user2id names, how would the relationship work? Just really need a bit of help wrapping my head around this.
I hope this makes sense, if you need any more information I will just edit the question.
Thanks for any help in advance!
Your question in not entirely clear as to the requirements. My design assumes the following about requirements:
People are linked together in pairs
Each pair owns zero, one, or more task records.
Each person can be assigned to zero, one, or more pairs. If not currently, then perhaps over time (past pairs, current pairs, future pairs).
I think your confusion revolves around the pairing. Instead think of it as teams. The fact that a team can have at most two people is beside the point; 2, 10, 100 does not matter because any number is handled the same way. That way is a Team table that has members assigned. Each person can belong to one or more teams, and each team can have one or more members. That means we have a Many-To-Many relationship between Person and Team. A many-to-many is a problem in relational design that is always solved by adding a third intermediate or "bridge" table. In this case, that bridge table is membership_.
Each team owns zero, one, or more tasks. Each task is owned by one and only one team. This is a simple One-To-Many relationship between Team and Task.
If these assumptions and constraints are correct, then you would have the following table design in a relational database such as Postgres.
I added a start_ and stop_ pair of fields on membership_ to show the idea that people may have past, present, or future assignments to teams.

Database for microblogging startup

I will do microblogging web service (for school, so don't blast me for lack of new idea) and I worry that DB could be often be overloaded (user could following other users or even tag so I suppouse that SELECT will be heavy - check 20 latest messages which contains all observing tags and user).
My idea is create another table, and store in it only statusID and userID (who should pick up message). Danger of that is, if some tag or user has many followers there will be a lot of record with that status ID. So, is it good idea? Or maybe better is used M2M relation? (one status -> many receivers)
I think most databases can easily handle large record sets. The responsibility to have it preform lies in your design with properly setting up the indexes. If you create the right indexes the select clauses should perform really well.
I'd go with a users table, a table to have the m2m relationship between users and messages table.
You can then do one select to find all of the users a user is following and then a second select in to get all of the messages of interest (sorting and limiting the results as appropriate). Extending this to tagging should be pretty simple.
This design should be fine for large numbers of users and messages as long as you index the right columns. If you got massive then you could also run the users tables and messages tables to different servers or have read only replicates. I wouldn't even worry about that for the moment - you'd need to be huge.
When implementing Collabinate (http://www.collabinate.com), a service-based engine for microblogging and shared activity streams, I used a graph database. The fact that people create posts and follow other people lends itself to a graph structure. With the right relationships and algorithms, this can be a very efficient and performant solution.