简体   繁体   中英

Optimal database design for extensibility

I'm designing a database and matching website for my internship using the Yii Framework, working mostly in PHP. Our goal is to allow administrative users complete flexibility in what information they want to display, so we're trying to keep the application dynamic. Because of this the idea is to the options/data in the database, instead of inside the code. I currently have a working setup, but i'm not sure if it's the right way to go about it. Long post guys, sorry. At the moment we have:

Relations
+ user HAS MANY user_phone
+ user_phone HAS MANY user
+ user_phone HAS user_phone_type

Tables
user <-- user_phone_assignment --> user_phone --> user_phone_type

user_phone_type
id INT PRIMARY KEY,
name VARCHAR(50) NOT NULL,
limit INT NOT NULL

Basic user profile information is stored in user, and to reduce repeated data in the instance of family and siblings, user_phone has an assignment table for potential many to many. The idea with user_phone_type is that we store a name such as "Home", "Work", "Fax", "Other", etc.

user_phone_type.limit < 0
+ field disabled, not displayed for actionCreatePhone
user_phone_type.limit = 0
+ field enabled, unlimited entries allowed, always displayed
user_phone_type.limit > 0
+ field enabled, displayed while count( user_phone) < user_phone_type.limit

I feel that this system is potentially viable, though I'm not sure if it's exactly the best way to go around doing this. Does anyone have any other options to keep the application flexible and database-oriented while maintaining easier relations? Perhaps some sort of configuration table setup, and we could store the config values in a local variable within the model or controller.

Be careful with your normalizations. Some things that look like potential many to many relationships are really just attributes. Phone numbers, and addresses, while you can model them as many to many, can be difficult to manage in that scenario because you have to deal with changing phone numbers and addresses. In a one to many model where a user as many addresses or phone numbers when an address or phone number changes, you just update it in the table. In a many to many model when an address or phone number changes, you have to determine whether it is the address that is changing or the user's assignment to a particular address that is changing. I have seen folks try to implement this, and it always ends up buggy because you are typically assigning say a mailing address and a customer address, or a home phone and a mobile phone, or a fax number, and the UI is typically not a many to many UI where you are selecting from a list of addresses or phone numbers.

Let's try a simple scenario with phone number:

Say a user#1 work phone number is 513-555-1234 and his mobile number is 513-555-4321. Say user#2 has the same work phone number 513-555-1234 and mobile number 513-555-4322.

Now say user#1 dropps their work phone number, or changes it to something else. What we want need to do in the case of dropping the number is to delete the link between users and phone numbers, because if we just delete the phone number field, user#2 will loose their work phone as well. Now we have to decide what to do if the user we just unlinked was the last user pointing at the phone number. Do we delete the phone number or keep it in case someone else picks it up? Changing the phone number is even more complex. Since there is no way of knowing whether the change is a correction o an invalid phone number, and it should change for everyone associated with it, we have to decide whether a change to a phone number will change it for everyone (ultimately a bad idea because if a user changes jobs and their work number changes, so does everyone else from the user's original work place which is obviously wrong), or if a change to the phone number affects only a single user assigned to it. Probably the best choice based on a standard user maintenance UI as it mimics the behavior of the one to many approach. But instead of just changing the phone number, you have to delete the link for the phone number, and then create a new phone number record and then link the customer to it. In both of these cases instead of just inserting a new record, you also have to check to ensure that the new phone number does not exist. If it does exist, you then will just link the user to the new number instead of creating the new number and linking to that. And really what does all that complexity save you? Not much. Maybe a little time verifying addresses, if you even do such a thing. Maybe a little space where 1% of your phone numbers overlap for a work phone number, but a large percentage of work phones are direct dial these days anyway, so that might not even be a real savings. I have even seen addresses separated into a different file and not managed at all, just a new address added whether it was a duplicate or not, no savings over just placing the address in the parent table.

So my opinion, and that is all this question will generate, is that you shouldn't try to worry about putting phone numbers or addresses in their own separate table unless there is a significant chance that many of the possible addresses or phone numbers will be missing, and that you will not write a blank address record in those cases. And even if you do keep them in a separate table, do not concern yourself with removing duplicates (by using a many to many relationship) because that will just add unnecessary complexity to your application.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM