Please start any new threads on our new
site at https://forums.sqlteam.com. We've got lots of great SQL Server
experts to answer whatever question you can come up with.
| Author |
Topic |
|
Page47
Master Smack Fu Yak Hacker
2878 Posts |
Posted - 2002-07-15 : 10:41:32
|
Lets say you have ...create table addrs ( addrid int identity(1,1) primary key, street1 varchar(50) not null, street2 varchar(50) not null, city varchar(30) not null, zip char(9) not null ) ... and you also have ...create table users ( login varchar(12) not null primary key )create table companies ( coname varchar(25) not null primary key ) Both the users and companies have one to N addresses. I suppose I need...create table addrbook ( addrid int not null primary key constraint fk_addrbook_addrid references addr(addrid), login varchar (12) null constraint fk_addrbook_login references users(login), coname varchar(25) null constraint fk_addrbook_coname references companies(coname), constraint ck_addrbook_login_coname check ((login is null and coname is not null) or (login is not null and coname is null)) Any better ideas?<O> |
|
|
robvolk
Most Valuable Yak
15732 Posts |
Posted - 2002-07-15 : 11:09:22
|
Well, this part isn't going to work:create table addrbook ( addrid int not null primary key constraint fk_addrbook_addrid references addr(addrid), login varchar (12) null constraint fk_addrbook_login references users(login), coname varchar(25) null constraint fk_addrbook_coname references companies(coname), constraint ck_addrbook_login_coname check ((login is null and coname is not null) or (login is not null and coname is null)) If you want to maintain a 1 to N relationship.I have a question: what's to prevent two different companies from having the exact same address? Not just street address, but actual floor/room/suite # too. I've yet to see two companies working in the exact same office space. It's just a detail, but you might want to consider it. |
 |
|
|
AndrewMurphy
Master Smack Fu Yak Hacker
2916 Posts |
Posted - 2002-07-15 : 11:15:50
|
| do you need to categorise the addresses.....ie by purpose...work, home, maildrop, wife's, lover's, etc??company secretary, company factory, legal address, home address of chairman/woman/person?also do you need (or does your design (need)) to allow for people to share an address at the same time? ie. 2 different tenants both sharing the same apartment?...your primary key on addressbook seems to only allow an address to be used once (on first reading)also what about last address.....2nd last address, etc....do you need to know/care when an address changed use....ie when did I move home address?....or is the need to know only the current address?what's there to stop an address being repeated twice (ormore) in the addrs table? |
 |
|
|
Page47
Master Smack Fu Yak Hacker
2878 Posts |
Posted - 2002-07-15 : 11:26:11
|
quote: I have a question: what's to prevent two different companies from having the exact same address? Not just street address, but actual floor/room/suite # too. I've yet to see two companies working in the exact same office space. It's just a detail, but you might want to consider it.
I suppose you are right, but I can't make a composite key cause either addrbook.login or addrbook.coname must be null (it either a companies address or a users address). Should I use a surroate key? I was thinking a user/co can have many addresses, but one address cannot be had by many user/co (in otherwords, two companies in the same suite would each have their own entry in addrs). How would I design to allow for that given the nullability of either login or coname?<O> |
 |
|
|
Page47
Master Smack Fu Yak Hacker
2878 Posts |
Posted - 2002-07-15 : 11:51:37
|
| Nevermind, I figured something else out... thanks anyway<O> |
 |
|
|
robvolk
Most Valuable Yak
15732 Posts |
Posted - 2002-07-15 : 11:55:59
|
quote: I suppose you are right, but I can't make a composite key cause either addrbook.login or addrbook.coname must be null (it either a companies address or a users address).
Actually that doesn't affect the addrs table. To address Andrew's concern about dupe addresses, you should also put a unique constraint on the 4 columns making up the full address. That's a bigger concern right now. Stick with addrid as the primary key. The addrbook table is not affected by this.quote: Should I use a surroate key?
For addrid, absolutely. Even I don't see much reason to keep 4 columns of address as a primary or foreign key. Just add the unique constraint.quote: I was thinking a user/co can have many addresses, but one address cannot be had by many user/co (in otherwords, two companies in the same suite would each have their own entry in addrs).
That would work now but not with the unique constraint in addrs. The problem is, if the address is EXACTLY the same, and the 2 co's do work in the same office, which addrid is the "correct" one? IOW, addrid #1 and #2 are the same address but refer to 2 different companies or people; why would it be wrong to say that ID 1 is correct only for 1 company and not the other.quote: How would I design to allow for that given the nullability of either login or coname?
I would suggest combining these into a single table like so:CREATE TABLE users (name varchar(25) not null primary key, IsCompany bit NOT NULL DEFAULT (0))As far as enforcing a length limit on logins, you can do that at the data entry level, or write a trigger:CREATE TRIGGER CheckNameLogin ON user FOR INSERT, UPDATE ASIF EXISTS (SELECT * FROM inserted WHERE Len(name)>12 AND IsCompany=0)ROLLBACK TRANSACTIONRAISERROR ('Logins cannot exceed 12 characters', 16, 1)I like this better because it prevents the (unlikely) possibility of having a login and company with the same name, and streamlines the addrbook table. Then you can do this:create table addrbook ( addrid int not null constraint fk_addrbook_addrid references addr(addrid), name varchar (25) null constraint fk_addrbook_login references users(name) constraint pk_addrbook PRIMARY KEY (addrid, name) ) Now you get the best of both worlds: logging a unique address only once, and allowing multiple people to share that address and/or have multiple addresses.Edited by - robvolk on 07/15/2002 11:58:01 |
 |
|
|
Page47
Master Smack Fu Yak Hacker
2878 Posts |
Posted - 2002-07-15 : 12:06:53
|
| WOW!! Put Companies and Users in the same table? That's very radical Rob. If I were to tell you that there was all manner of supporting data for each of these entities which isn't shared, would that change your position? If I were to tell you that not every user is associated with a company (in fact only a small % of users have company data), would that change your position? So my Departments table would reference users(name)? So my UserRoles table would reference users(name)? How would make people users not have departments and company users not have roles?I was just going to with a UsersAddressBook and CompanyAddressBook with composite keys on AddrID and {Login,CoName}(respectively). Sure, I'll probably have to deal with preventing a dupe between a persons work addr and a companies addr for the company that person is related too, but I can do that in the proc.<O> |
 |
|
|
robvolk
Most Valuable Yak
15732 Posts |
Posted - 2002-07-15 : 12:22:38
|
quote: If I were to tell you that there was all manner of supporting data for each of these entities which isn't shared, would that change your position?
Nope, I would have the same position as I usually state to newbie questions:POST ALL OF YOUR ACTUAL TABLE STRUCTURES! You're not playing fair in leaving out the important stuff!quote: If I were to tell you that not every user is associated with a company (in fact only a small % of users have company data), would that change your position?
No. You could add a UserCompanies table with 2 columns, one for the person's ID and one for the company's ID. Assuming you don't already have a table like this...you DIDN'T POST YOUR DDL!  quote: So my Departments table would reference users(name)? So my UserRoles table would reference users(name)?
You could do something similar to my earlier post: roll both UserRoles and Departments into a combined table and use an IsDepartment flag, etc., or add a "Type" char/varchar column indicating "role" or "department" or any other kind of attribute for the column. I think that might still work. The primary key could remain the single "name" column, or use the name and type column pairs, depending on whether a person/company can be both types.quote: How would make people users not have departments and company users not have roles?
Uhhhh, English? If you use the two-column combined RolesDepartments structure, you can simply add a row for every role/department a person/company can have. Of course, SINCE I DON'T HAVE YOUR EXACT DDL...I'm LOVING the irony here... quote: I was just going to with a UsersAddressBook and CompanyAddressBook with composite keys on AddrID and {Login,CoName}(respectively). Sure, I'll probably have to deal with preventing a dupe between a persons work addr and a companies addr for the company that person is related too, but I can do that in the proc.
Nothing wrong with this approach either; as long as it works it's the right way to do it.I was thinking that since you love to dive deep into esoteric design issues I might offer up an alternative that uses natural keys |
 |
|
|
Page47
Master Smack Fu Yak Hacker
2878 Posts |
Posted - 2002-07-15 : 12:55:12
|
You're such a prick ....I've got a design that is going to work for me, so lets move out of the realm of my actual problem and into the world of the esoteric design issues around you're ideas....So lets say I created (as you suggest)...create table UsersRolesDepartmentsSubscriptionsPersonnelPrivsAuthenticationFailures ( username varchar(25) not null, relationshiptype varchar(20) not null constraint fk references relationships(relationshiptype), deptname varchar(25) null, subscription varchar(20) null, coname varchar(25) null, priv varchar(50) null, logonfailures tinyint null, firstfailure smalldatetime null constraint pk_IDontWantToTypeThisLongName Primary Key(username,relationshiptype))create table relationships ( relationshiptype varchar(20) not null primary key ) First, how would you suggest allowing a user to have multiple subscriptions? Second, aren't all of these nullable column sort-of like partial dependencies on the relationshiptype column, and thus, fail 2NF?quote:
quote: How would make people users not have departments and company users not have roles?
Uhhhh, English?
Interesting, Mr. Volk, you seem to make a strong case against your own arguement. It's impossible(read: very hard) to talk about the data. What I am trying to ask is "How would you make sure that users-that-are-people do not have departments and users-that-are-companies do not have roles?"<O> |
 |
|
|
robvolk
Most Valuable Yak
15732 Posts |
Posted - 2002-07-15 : 13:48:59
|
Having no idea what this table UsersRolesDepartmentsSubscriptionsPersonnelPrivsAuthenticationFailures is supposed to replace in your original structure, I can't say that it's better or worse (probably worse though), and sorry, that's not how I would've suggested or designed it. Of course, IF I HAD THE DDL for the whole database then I might be able to say more definitively... The thing is, if you have a particular issue with a single table and you want to solve it, you have to consider it within the context of the ENTIRE DATABASE. I know you already know that, but this example is a good illustration. Changing the tables to use my ideas works for the immediate problem of the address book table, but DOES NOT work for the other tables.My "Uhhhh? English?" comments relates to the part in red: it's got some grammatical errors. That's all I was trying to point out.Design-wise, again you already know that there's more than one way to skin a cat. You can treat people and companies as entirely separate things; that certainly makes sense to me. But in a higher-level, more abstract database design (the kind of shit that Pascal and Date deal with exclusively), you have a table/entity/relation/whatever-the-hell-they-call-it-today that relates to both users and companies. Those relationships differ, so you have to either compromise one table's degree of normalization or redesign the other two to accomodate the relationships. Neither approach is "wrong". Hopefully it underscores a point I firmly believe in: there is no "perfect" design or data model. Except perhaps the one that leads to the fewest compromises.And besides Chris and Fabian, and maybe byrmol, no one is gonna shoot you if you have a table in 2NF or 1NF. I really like your remark here:http://www.sqlteam.com/Forums/topic.asp?TOPIC_ID=17296About "It depends where the books are located, not how many you need". If you can physically get the books (rows) out of the library (tables) with the least hassle or effort, then you've got the right design, whether it's logically OK or not. |
 |
|
|
Page47
Master Smack Fu Yak Hacker
2878 Posts |
Posted - 2002-07-15 : 14:10:10
|
Point taken...I found the unique design problem interesting. I had simple one-to-many between users and addrs, so I implemented originally with a login fk in my addr table. Simple enough. The rules didn't specify a many-to-many, so there was no need to create a third table with a composite (login,addrid) key. Obviously, with those rules, the two table design(addrs and users) seemed superior to a three table design(addrs, users and useraddrs). But then along comes a new rule: Companies (a very diff entity in my database) can have addrs too. I was so happy with my simple two table design, but couldn't find a good way to shoehorn the new rule into my design. As is the source for much 'Duct-tape' in our industry, I couldn't initially see a clean solution...quote: My "Uhhhh? English?" comments relates to the part in red: it's got some grammatical errors.
Sorry, I missed your meaning even on the second read!!! I wish English had a SET PARSEONLY ON option .....I can't type/spell for shyt...you should no that bye now ....BWAHAHAHA<O> |
 |
|
|
|
|
|
|
|