6

Let me start this out by saying I'm anything but a database expert. I'm working on some code written by someone else and I've noticed a lot of 1-1 relationships between tables. Here's an example:

tblPropertyRecord
   pID
   hasPhotos
   hasVideo
   comment
   headline

tblPropertyLocation
   ID
   pID
   country
   region
   city
   zip
   street_address

tblPropertyOther
   ID
   pID
   upload_path
   isApproved
   isPaid

This doesn't encompass every field for a property - there are about 35 fields in total per record, but each table has, and can only have ONE entry for each record 1 to 1 to 1 ... I guess is the way to describe it?

Whats the benefit of this over just having tblPropertyRecord with 35 fields? I understand the point of many to 1, 1 to many, many to many ... but this just seems like added confusion with no real benefit.

Will
  • 5,370
  • 9
  • 35
  • 48
  • possible duplicate of [Is there ever a time where using a database 1:1 relationship makes sense?](http://stackoverflow.com/questions/517417/is-there-ever-a-time-where-using-a-database-11-relationship-makes-sense) – Peter Bailey Nov 08 '10 at 17:53
  • its always 1:1. All 3 (actually 5 in the application) tables get one entry per field and that makes up a listing. It seems insane to me, but I thought perhaps its just my inexperience. – Will Nov 08 '10 at 17:53
  • @peter: Thanks for that link. The first answer seems to make a LOT of sense, and it tells me that this DB schema is more or less trash (all fields are always filled out for all records). This doesn't really surprise me as the code is riddled with SQL-Injection flaws and other strangeness (booleans stored as enums, for example) @user359996: The nature of the data is such that there should never be more then 1:1 -- a listing can't have multiple addresses, as a listing is a single piece of property within this software. – Will Nov 08 '10 at 17:56
  • 2
    It seems as if, conceptually, the relation between the entities is indeed 1:1(:1:1:1...). Barring exotic requirements (you haven't mentioned any), I see no reason to have multiple tables. Maybe this was a demented attempt to map objects or other structures directly to tables? – user359996 Nov 08 '10 at 17:58
  • 2
    Could you please inspect the answers, vote, and choose one. – PerformanceDBA Dec 15 '10 at 10:06

8 Answers8

5

The tables might be 1-1 however the relationship might actually be 1 to 0..1 - they might be using the extra tables to avoid having a very sparsely populated table.

SorcyCat
  • 1,206
  • 10
  • 19
3

One common case would be due to legacy database support (i.e. you are extending onto the data store of an existing lecacy database where you do not want to risk breaking existing functionality by adding new columns).

If this is greenfield, and if you are 100% sure that the fields in question will always be one to one, then (generally) there's no reason not to include them in the same table. I expect there are some edge cases, like data partitioning, or optimizing your record for a specific page size, etc.

Bob Palmer
  • 4,714
  • 2
  • 27
  • 31
2

Quick quote from the Hibernate documentation on this subject

There are three cases for one-to-one associations: either the associated entities share the same primary keys values, a foreign key is held by one of the entities (note that this FK column in the database should be constrained unique to simulate one-to-one multiplicity), or a association table is used to store the link between the 2 entities (a unique constraint has to be defined on each fk to ensure the one to one multiplicity).

If the above does not hold for your scenario, then you should consider refactoring.

Edit for clarification after comments

  1. If two entities share the same PK then they are effectively one entity (1:1)
  2. If one of the two entities has a unique FK into the other then they are effectively one entity, but with an existence option (1:0..1) - optional extra properties
  3. If an association table has unique FKs into each of the two entities then they are effecitvely one entity, but with a bi-directional existence option (0..1:0..1) - optional mix of 2 sets of properties

Hope that clears up the slightly abstract language of the quote.

Gary
  • 7,167
  • 3
  • 38
  • 57
  • 1
    -1 Disagree with most of that, it is not technically sound (which may be disagreeing with the article,, not yo, but you postedit). – PerformanceDBA Nov 10 '10 at 05:37
  • @PerformanceDBA I disagree that it is not technically sound. I have edited the article to clarify in the hope that you reconsider. – Gary Nov 10 '10 at 09:04
  • 1
    @Gary. The whole article is based on a fixed approach to make an OO language app coder's life easier. It is the anti-thesis of Relational Db design and Standards (independence from ALL apps). Classes do not need to "mapped"; Java coders need to be taught RDB principles and SQL (it is an RDB container, not a ODB container, right?). Abstract language is very silly when we have had precise Relational language for 20 years. Read my post re the only legitimate reason. Even if you could justify doing silly things for a Java app+closed restricted non-db, such concepts shud not be applied to RDB – PerformanceDBA Nov 10 '10 at 09:27
  • @PerformanceDBA Thanks for your clarfication. I can see that from your standpoint (all applications using an RDBMS should adhere to relational principles) that you would view this as technically incorrect. Further debate on this issue is outside the scope of the OP. – Gary Nov 10 '10 at 09:52
  • 1
    @Gary. To clarify. Not that the apps "should adhere", but that the Rdb is (a) Independent (b) Relational and (c) compliant with Standards. Once that is done, then any app using the Rdb has to use it with whatever platform limitation exist for the app language. But modelling then Rdb to fit a single app or limited app language, or to make it easy for a certain app language to use, and breaking Rdb principles in doing so, is a very close-minded thing to do. You've lost the power of "relational" and "database". Much easier and cheaper for you if you switch to file systems. – PerformanceDBA Nov 10 '10 at 13:04
  • 1
    The apps can remain independent and adhere to any principles as required, not Rdb proinciples. But when it comes to accessing the Rdb, it would help if the coders understood Rdb, rather than turning it into chicken soup, and using it as a class-based record storage system. – PerformanceDBA Nov 10 '10 at 13:06
1

Typically speaking, I break these sorts of properties into multiple tables when I have a group of properties that could be NULL under some circumstances. It's hard to tell from the schema you've posted if that's a reasonable explanation for separating this information.

Is tblPropertyRecord the parent table in all of these relationships? If so, are there ever situations where a user could create a record for a new property and not fill out part of the information contained in the other tables?

Alternatively, does your website allow users to enter some of the data on one page, before proceeding to another step and entering more information? If that's the case, then perhaps the original designer is saving information as the user progresses.

Anyway, I'd say that if neither of these conditions are true, then there isn't a really strong reason to separate the data across multiple tables.

Edit: I see your comment about the website always entering all of the fields, so it's probably safe for you to assume that this data should be in a single table.

jwheron
  • 2,553
  • 2
  • 30
  • 40
1

I think it is clear that, given the info in your answers, and there are no Nullable columns, all five tables should be rolled into one table. That, however does not sound reasonable at all (35 "fields" is pretty much a read flag that you have a flat file, not Normalised). It would be good for you to inspect the real data, all use cases, thoroughly.

Designing databases for application requirements is not an acceptable reason for such poor design. If the column is 1::1 with the PK, then it must be in the table. And not, if it is not.

The only legitimate reason for splitting certain columns off into a separate 1::1 table is:

  • for Nullable columns (optional or missing values)

  • where the column is therefore 1::0-1 with the PK.

    (Commercial DBMS automatically place [all] BOLBs off-row, on separate devices, and allow device management; for the freeware end of town, of course you have to do all that sort of basic physical optomisation yourself.)

    (The small end of town cannot handle large rows either, so that's another commercially illegitimate reason that is legitimate in that case.)

Then you can support an Unique index on one of those columns:

CREATE TABLE Part (
    PartId,
    Description,
    EtCetera                   -- Optional SerialNo here cannot be made Unique
    )
CREATE UNIQUE CLUSTERED INDEX UC_PartId
    ON Part (PartId)
CREATE TABLE PartSerial ( PartId, SerialNo, EtCetera ) CREATE UNIQUE NONCLUSTERED INDEX UC_PartId ON PartSerial (PartId) CREATE UNIQUE CLUSTERED INDEX U_SerialNo ON PartSerial (SerialNo) -- SerialNo can now be Unique ALTER TABLE PartSerial ADD CONSTRAINT FOREIGN KEY (PartId) REFERENCES Part (PartId)

There is another mistake in the four tables. The ID column (and Unique Index) is totally and completely redundant. The pID is both the Primary Key and the Foreign Key to tblPropertyRecord.

PerformanceDBA
  • 32,198
  • 10
  • 64
  • 90
  • I know you don't like any dissenting comments or opinions, but 1:1 could be an *implementation* detail. Eg you have an associated large BLOBs and want them on a separate filegroup. Surely with your *vast* and unparalled experience you'd have seen this before? – gbn Nov 28 '10 at 20:14
  • 2
    @gbn. The nappy rash is really getting to you, huh ? Post updated. – PerformanceDBA Nov 29 '10 at 11:20
0

1-1 tables are also one approach when modeling inheritance. From the table-names in your example it doesn't seem to be the case though.

How do you effectively model inheritance in a database?

Community
  • 1
  • 1
Ozzy
  • 1,712
  • 11
  • 14
  • 1
    1-1 tables are simply incorrect for a Relational db. All these idiots "modelling" inheritance from an OO perspective into a Rdb are misusiing it, and the power of an Rdb is lost to them. They are not modelling an Rdb based on their data, they are simply implementing OO structures in an Rdb. – PerformanceDBA Nov 20 '10 at 06:10
0

We sometimes implement 1 to 1 tables based on modular functionality. For example, let's say we have a Person object that is used across modules. Now, some modules may need to have additional properties for that Person. Like Postal Address or Phone Numbers, whereas others don't.

This is a form of table "inheritance" in that we can expand out the functionality of a Person without impacting previous code. For us this means that the relationship is one to one or zero.

The only other reason I can think of separating out the fields like that is if the tables are big and most of the fields aren't used in queries. For example, if nearly all of the queries just take the primary table into concern, you could conceivably have the entire table cached in ram for faster response. Or, you could partition the sub tables onto different drives if data size is an issue.

However, if a great number of your queries join those tables together, then I'd consider that an absolute waste.

NotMe
  • 87,343
  • 27
  • 171
  • 245
  • They do (lots of joins) - the more I work on this software package, the more I start to think the original coder was just terrible – Will Nov 09 '10 at 14:41
  • 2
    -1 Have your people **not heard of** (a) SELECT column_list instead of SELECT * ? (a) Views ? (c) tightly binding the database to the app renders it a non-database, a container for the single app, and closed/restrictive to any other apps and users ? – PerformanceDBA Nov 10 '10 at 06:04
  • @PerformanceDBA: we do use the SELECT column_list format, but that isn't the issue; if you bothered reading the answer you'd understand that. – NotMe Nov 10 '10 at 07:03
  • 1
    @Chris. Er, read before. Re-read again now. Have Java coders of my own. You post may apply to sub-standard closed dbs glued to the hip of a Java app; they do not apply to the larger audience of non-substandard non-Java Relational Db. "inheritance" hardwired into the db; inability to extend the db without impacting previous code. Hilarious. Point being, your comments certainly apply to your sub-standard Java implementation, and your non-relational db; they do not apply to Relational Dbs. Which is the question. – PerformanceDBA Nov 10 '10 at 09:33
  • @PerformanceDBA: Not sure where you are getting Java from, haven't used that in 10 years. Let's say you have a core and 2 *optional* modules. The core defines a person (first, last, email). 1 optional adds a requirement for SSN. The other adds a requirement for physical attributes like eye color. Oh, and they can be deployed separately. Do you still advocate putting it all in one table? That would be more than a bit short sighted. – NotMe Nov 10 '10 at 13:19
  • 1
    @Chris. Shortsighted or not is a personal opinion. It is a Db question, so I am interested in the technical Db facts. I was responding to y post. Splitting tables for "modular functionality", deployment timeframes, "inheritance" & all that, is wrong. If they are true optional columns, then it is right. "if most columns are not used in queries" is premature optimisation, wrong, affects others, better off caching the index only. Inability to extend Rdb without impacting code is evidence that you have broken more than a few rules, and it is a closed, one-app-only storage system. – PerformanceDBA Nov 10 '10 at 13:54
0

Number one thing in any database management scenario: Know Your Data

If you know your data, and you know you'll never have a need for more than one big table. Don't make is more complicated just because it doesn't look right or doesn't have that normalized feel to it.

Know your data and act appropriately.

johnny
  • 19,272
  • 52
  • 157
  • 259