Showing posts with label dbdesign. Show all posts
Showing posts with label dbdesign. Show all posts

Tuesday, February 14, 2012

DBDesign Q2:

Hi All!

I like employee and department scenario from DBDesgin Q.
It looks more intuitive than my previous sample.

************************************************** *********************
Business rule:

Each employee works only in one department.
Department is managed by only one of employee who works in this
department.
One employee cannot work for two different departments and one
employee cannot manage two different departments

************************************************** ************************

*********
SolutionA(not good. Two entity referent each other)

Department (DepartmentID PK, Name, eEmployeeID FK)
Employee (EmployeeID PK , Name, , dDepartmetnID FK)
To add records in solutionA to Department and Employee tables:
Add a record to Department with eEmployeeID= NULL
Add Employee records
Set eEmployeeID to value in Department table

*********
Solution B: (I think it is cleaner than A, but there is a whole)
Department (DepartmentID PK, Name)
Employee (EmployeeID PK , Name, , dDepartmetnID FK)
(the next is subtyping of employee)
DepartmentMngr(EmployeeID PK/FK, dDepartmentID FK/U1)

It will satisfy bus. rule, but there is a whole.
Employee who is a manager can reference one department in Employee
table and the other department in DepartmentMngr.

*********
Solution C.(Problem: How buss. rule can be forced that only one
employee from department is a manager?)
Department (DepartmentID PK, Name)
Employee (EmployeeID PK , Name, , dDepartmetnID FK, eEmployeeID FK)

Q. How buss. Rule can be forced that only one employee from
department is a manager?

Are there any suggestions about implementing the above business rule?
Which of implementations are you in favor?

Thank you in advance,
Andy.The following seems to match your business rules. Treat Department Manager
as an attribute of the Department rather than the Employee.

CREATE SCHEMA AUTHORIZATION dbo

CREATE TABLE Employees (empno INTEGER PRIMARY KEY, deptno INTEGER NOT NULL
REFERENCES Departments (deptno), UNIQUE (deptno, empno))

CREATE TABLE Departments (deptno INTEGER PRIMARY KEY, deptname VARCHAR(20)
NOT NULL UNIQUE, deptmanager_empno INTEGER NOT NULL, FOREIGN KEY (deptno,
deptmanager_empno) REFERENCES Employees (deptno, empno))

The usual caveat about design questions applies: it's very difficult to give
design advice online without the opportunity to research a particular
situation in detail.

--
David Portas
----
Please reply only to the newsgroup
--|||net__space@.hotmail.com (Andy) wrote in message news:<edb90340.0311262009.33976f1a@.posting.google.com>...
> Hi All!
> I like employee and department scenario from DBDesgin Q.
> It looks more intuitive than my previous sample.
> ************************************************** *********************
> Business rule:
> Each employee works only in one department.
> Department is managed by only one of employee who works in this
> department.
> One employee cannot work for two different departments and one
> employee cannot manage two different departments
> ************************************************** ************************
> *********
> SolutionA(not good. Two entity referent each other)
> Department (DepartmentID PK, Name, eEmployeeID FK)
> Employee (EmployeeID PK , Name, ?, dDepartmetnID FK)
> To add records in solutionA to Department and Employee tables:
> Add a record to Department with eEmployeeID= NULL
> Add Employee records
> Set eEmployeeID to value in Department table

I don't find this objectionable. It may pose a technical challenge,
but that can be overcome. For example, Oracle allows constraint
checking to be deferred until the end of the transaction, so you can
do this:

insert into department( departmentid, eemployeeid ) values
('D1','E1');
insert into employee (employeeid, name, ddepartmentid) values
('E1','Smith','D1');
commit;

To enforce the rule that the manager of the department must also be an
employee in the department would require an additional database
constraint (or "assertion"), which would also have to be checked at
the end of the transaction. Not all DBMS products support this though
(Oracle doesn't).

> Solution B: (I think it is cleaner than A, but there is a whole)
> Department (DepartmentID PK, Name)
> Employee (EmployeeID PK , Name, ?, dDepartmetnID FK)
> (the next is subtyping of employee)
> DepartmentMngr(EmployeeID PK/FK, dDepartmentID FK/U1)
> It will satisfy bus. rule, but there is a whole.
> Employee who is a manager can reference one department in Employee
> table and the other department in DepartmentMngr.

Another hole is that a department can be set up with no manager at
all. Again, database constraints deferred until the end of the
transaction would be required to enforce these rules (if the DBMS
supports such constraints).

> Solution C.(Problem: How buss. rule can be forced that only one
> employee from department is a manager?)
> Department (DepartmentID PK, Name)
> Employee (EmployeeID PK , Name, ?, dDepartmetnID FK, eEmployeeID FK)
> Q. How buss. Rule can be forced that only one employee from
> department is a manager?

I don't understand this one. What is employee.eemployeeid?

> Are there any suggestions about implementing the above business rule?
> Which of implementations are you in favor?

Out of those, I'd stick with solution A. Another possibility you
didn't mention is this:

Department (DepartmentID PK, Name)
Employee (EmployeeID PK , Name, ?, dDepartmetnID FK, manager_flag)

The "manager_flag" column is a boolean or yes/no type value that
specifies whether the employee is manager of the department he/she
belongs to. That enforces the rule that an employee can only manage
his own department, but does not enforce the rule that a department
must have one and only one manager - again, a deferred database
constraint is required.

Whichever solution you choose requires the addition of database
(inter-table) constraints that are deferred until the end of the
transaction. Combinations of primary, unique and foreign keys alone
cannot enforce all the rules. With most (all?) existing DBMS
products, this means that the business rules simply cannot all be
enforced in the database; some must be enforced in the application, or
by forcing use of stored procedures to maintain the data, or not
enforced at all (except by exception reporting and manual
intervention).|||well,

i just can't image how these two can be used! can you continue your sample
and try to populate the tables with some sample data.

</wqw
"David Portas" <REMOVE_BEFORE_REPLYING_dportas@.acm.org> wrote in message
news:Bp6dna5zxsvBf1iiRVn-hQ@.giganews.com...
> The following seems to match your business rules. Treat Department Manager
> as an attribute of the Department rather than the Employee.
> CREATE SCHEMA AUTHORIZATION dbo
> CREATE TABLE Employees (empno INTEGER PRIMARY KEY, deptno INTEGER NOT NULL
> REFERENCES Departments (deptno), UNIQUE (deptno, empno))
> CREATE TABLE Departments (deptno INTEGER PRIMARY KEY, deptname VARCHAR(20)
> NOT NULL UNIQUE, deptmanager_empno INTEGER NOT NULL, FOREIGN KEY (deptno,
> deptmanager_empno) REFERENCES Employees (deptno, empno))
> The usual caveat about design questions applies: it's very difficult to
give
> design advice online without the opportunity to research a particular
> situation in detail.
> --
> David Portas
> ----
> Please reply only to the newsgroup
> --|||> Solution B: (I think it is cleaner than A, but there is a whole)
> Department (DepartmentID PK, Name)
> Employee (EmployeeID PK , Name, ., dDepartmetnID FK)
> (the next is subtyping of employee)
> DepartmentMngr(EmployeeID PK/FK, dDepartmentID FK/U1)
> It will satisfy bus. rule, but there is a whole.
> Employee who is a manager can reference one department in Employee
> table and the other department in DepartmentMngr.

it's not clear what's the FK on DepartmentMngr refers to. try composite one
like this:

FOREIGN KEY(EmployeeID, dDepartmentID )
REFERENCES Employee (EmployeeID, dDepartmentID)

> Solution C.(Problem: How buss. rule can be forced that only one
> employee from department is a manager?)
> Department (DepartmentID PK, Name)
> Employee (EmployeeID PK , Name, ., dDepartmetnID FK, eEmployeeID FK)
> Q. How buss. Rule can be forced that only one employee from
> department is a manager?

if you go with the "manager_flag" to enforce "only one employee from a
department is its manager" you can use an indexed view. something like this:

SELECT dDepartmetnID
FROM Employee
WHERE manager_flag=1

and then create the PK on dDepartmetnID -- this will ensure no two employees
are manager of the same department.

cheers,
</wqw|||Ah! you spotted my deliberate mistake ;-).

Make Deptmanager_empno NULLable. Obviously that's a compromise to Andy's
requirements. Possibly you could make it non-nullable once you've populated
both tables though that could make for some interesting logical conundrums
if you need to carry out a management reshuffle between departments!

Possibly it might be acceptable to leave Deptmanager_empno nullable but add
a UNIQUE constraint so that no more than one department can be without a
manager at any one time.

--
David Portas
----
Please reply only to the newsgroup
--|||> > *********
> > SolutionA(not good. Two entity referent each other)
> > Department (DepartmentID PK, Name, eEmployeeID FK)
> > Employee (EmployeeID PK , Name, ?, dDepartmetnID FK)
> > To add records in solutionA to Department and Employee tables:
> > Add a record to Department with eEmployeeID= NULL
> > Add Employee records
> > Set eEmployeeID to value in Department table
> I don't find this objectionable. It may pose a technical challenge,
> but that can be overcome. For example, Oracle allows constraint
> checking to be deferred until the end of the transaction, so you can
> do this:
> insert into department( departmentid, eemployeeid ) values
> ('D1','E1');
> insert into employee (employeeid, name, ddepartmentid) values
> ('E1','Smith','D1');
> commit;
> To enforce the rule that the manager of the department must also be an
> employee in the department would require an additional database
> constraint (or "assertion"), which would also have to be checked at
> the end of the transaction. Not all DBMS products support this though
> (Oracle doesn't).

Are you ok with the style that employee references department table
and
department references employee table?

> > Solution C.(Problem: How buss. rule can be forced that only one
> > employee from department is a manager?)
> > Department (DepartmentID PK, Name)
> > Employee (EmployeeID PK , Name, ?, dDepartmetnID FK, eEmployeeID FK)
> > Q. How buss. Rule can be forced that only one employee from
> > department is a manager?
> I don't understand this one. What is employee.eemployeeid?

Employee.eEmployeeID(FK) references Employee.EmployeeID(PK)

> Out of those, I'd stick with solution A. Another possibility you
> didn't mention is this:
> Department (DepartmentID PK, Name)
> Employee (EmployeeID PK , Name, ?, dDepartmetnID FK, manager_flag)
> The "manager_flag" column is a boolean or yes/no type value that
> specifies whether the employee is manager of the department he/she
> belongs to. That enforces the rule that an employee can only manage
> his own department, but does not enforce the rule that a department
> must have one and only one manager - again, a deferred database
> constraint is required.
I am personally in favour of the solution with the flag. The problem
is more than one employee can be a managers or no managers at all if
all flag are false, but this can be fixed with a trigger.

Solution A. The problem is that the manager (Department.eEmployeeID)
can point to employee ((Employee.EmployeeID) from different department

Between the solution A and the proposed solution with flag which one
are you in favour of?|||"Vlad Vissoultchev" <wqweto@.nospam.myrealbox.com> wrote in message news:<uCXMLGStDHA.2060@.TK2MSFTNGP10.phx.gbl>...
> > Solution B: (I think it is cleaner than A, but there is a whole)
> > Department (DepartmentID PK, Name)
> > Employee (EmployeeID PK , Name, ., dDepartmetnID FK)
> > (the next is subtyping of employee)
> > DepartmentMngr(EmployeeID PK/FK, dDepartmentID FK/U1)
> > It will satisfy bus. rule, but there is a whole.
> > Employee who is a manager can reference one department in Employee
> > table and the other department in DepartmentMngr.
> it's not clear what's the FK on DepartmentMngr refers to.

DepartmentMngr.dDepartmentID refers Department.DepartmentID|||net__space@.hotmail.com (Andy) wrote in message news:<edb90340.0311272005.3500e39d@.posting.google.com>...
> > > *********
> > > SolutionA(not good. Two entity referent each other)
> > > > Department (DepartmentID PK, Name, eEmployeeID FK)
> > > Employee (EmployeeID PK , Name, ?, dDepartmetnID FK)
> > > To add records in solutionA to Department and Employee tables:
> > > Add a record to Department with eEmployeeID= NULL
> > > Add Employee records
> > > Set eEmployeeID to value in Department table
> > I don't find this objectionable. It may pose a technical challenge,
> > but that can be overcome. For example, Oracle allows constraint
> > checking to be deferred until the end of the transaction, so you can
> > do this:
> > insert into department( departmentid, eemployeeid ) values
> > ('D1','E1');
> > insert into employee (employeeid, name, ddepartmentid) values
> > ('E1','Smith','D1');
> > commit;
> > To enforce the rule that the manager of the department must also be an
> > employee in the department would require an additional database
> > constraint (or "assertion"), which would also have to be checked at
> > the end of the transaction. Not all DBMS products support this though
> > (Oracle doesn't).
> Are you ok with the style that employee references department table
> and
> department references employee table?
Yes, like I just said: "I don't find this objectionable." In reality,
I would probably allow a department to exist without a manager
assigned - a company might want to define its new department structure
first, and assign managers later. But if the rule really were that
every department MUST have a manager and every employee MUST be in a
department, then I would use deferred constraints to handle that.

> > > Solution C.(Problem: How buss. rule can be forced that only one
> > > employee from department is a manager?)
> > > Department (DepartmentID PK, Name)
> > > Employee (EmployeeID PK , Name, ?, dDepartmetnID FK, eEmployeeID FK)
> > > > Q. How buss. Rule can be forced that only one employee from
> > > department is a manager?
> > I don't understand this one. What is employee.eemployeeid?
> Employee.eEmployeeID(FK) references Employee.EmployeeID(PK)

OK, so this is a diferrent set up altogether: now it is employees who
are managed by other employees, and departments are not managed at
all. May be valid, but it isn't the same thing.

> > Out of those, I'd stick with solution A. Another possibility you
> > didn't mention is this:
> > Department (DepartmentID PK, Name)
> > Employee (EmployeeID PK , Name, ?, dDepartmetnID FK, manager_flag)
> > The "manager_flag" column is a boolean or yes/no type value that
> > specifies whether the employee is manager of the department he/she
> > belongs to. That enforces the rule that an employee can only manage
> > his own department, but does not enforce the rule that a department
> > must have one and only one manager - again, a deferred database
> > constraint is required.
> I am personally in favour of the solution with the flag. The problem
> is more than one employee can be a managers or no managers at all if
> all flag are false, but this can be fixed with a trigger.

I don't think it's that simple actually. Suppose you have a
department D1 with 2 employees E1 and E2, and that E1 is flagged as
being the manager. If a department must always have exactly 1
manager, how do you change the manager from E1 to E2? You can't
"unflag" E1 first, because then there would be no manager, and you
can't flag E2 first, because then there would be 2 managers.
This is a check that must be done at the transaction level (after both
updates), whereas triggers fire at the statement level.

Maybe you could get around that using a fancy update statement like:

update employee
set manager_flag = case when manager_flag='Y' then 'N' else 'Y' end
where employee_id in (E1, E2);

Another solution might be to use a trigger on employee to maintain a
new column "number_of_managers" on department. We can then add a
check constraint on this column: check(number_of_managers = 1). As
long as we can DEFER this check until the end of the transaction, we
are OK.

> Solution A. The problem is that the manager (Department.eEmployeeID)
> can point to employee ((Employee.EmployeeID) from different department
> Between the solution A and the proposed solution with flag which one
> are you in favour of?

Generally, I'd go for A because if every department is managed by 1
employee, that sounds like a foreign key from department to employee
to me.

DBDesign Q

Can two entities have more than one relationship between them?

A(A_ID PK,.., bID FK)

B(B_ID PK,.., aID FK)

A.bID refers to B.B_ID
B.aID refers to A_ID

2. Does it make sense?

Product (ProductID PK, Name,, SpecialAttrID FK)

Attribute (AttrID PK, Name,.,ProductID FK)

Product can have many attributes. One attribute belongs to only one product.
There is only one main("special") attribute for each product

Thank you in advance,
Andynet__space@.hotmail.com (Andy) wrote in message news:<edb90340.0311232036.e0eeae5@.posting.google.com>...
> Can two entities have more than one relationship between them?
> A(A_ID PK,?.., bID FK)
> B(B_ID PK,?.., aID FK)
> A.bID refers to B.B_ID
> B.aID refers to A_ID
Yes, for example:

Employee E1 works in Department D1
Department D1 is managed by Employee D2

> 2. Does it make sense?
> Product (ProductID PK, Name,?, SpecialAttrID FK)
> Attribute (AttrID PK, Name,?.,ProductID FK)
> Product can have many attributes. One attribute belongs to only one product.
> There is only one main("special") attribute for each product
> Thank you in advance,
> Andy

A lot of people do this, seduced by how generic and flexible it is.
It also saves the bother of actually working out what those pesky
atrributes actually are in advance (aka "analysis"). The big downside
comes when you want to query this data, and find out how complex the
queries become. For example:

select p.name
from product p, attribute a1, attribute a2, attribute a3
where p.productid = a1.productid
and a1.name = 'Color'
and a1.value = 'Red'
and p.productid = a2.productid
and a2.name = '100'
and a2.value = 'Medium'
and p.productid = a3.productid
and a3.name = 'Width'
and a3.value = '7.5'

instead of:

select p.name
from product p
where p.color = 'Red'
and p.length = 100
and p.width = 7.5;|||Hi,

I think i does'nt make sence.

The reason is for the creation of each table , another table should
exists already vice-versa.

So i think u can not create even a single table as that regard.

With thanks|||It is correct on an ERD, but incorrect in a relational schema.

"Andy" <net__space@.hotmail.com> wrote in message
news:edb90340.0311232036.e0eeae5@.posting.google.co m...
> Can two entities have more than one relationship between them?
> A(A_ID PK,..., bID FK)
> B(B_ID PK,..., aID FK)
> A.bID refers to B.B_ID
> B.aID refers to A_ID
> 2. Does it make sense?
> Product (ProductID PK, Name,., SpecialAttrID FK)
> Attribute (AttrID PK, Name,..,ProductID FK)
> Product can have many attributes. One attribute belongs to only one
product.
> There is only one main("special") attribute for each product
> Thank you in advance,
> Andy|||"Alan" <alan@.erols.com> wrote in message
news:bpthmj$1t348d$1@.ID-114862.news.uni-berlin.de...
> It is correct on an ERD, but incorrect in a relational schema.

That's a rather astounding statement. How do you propose to support your
assertion?

> "Andy" <net__space@.hotmail.com> wrote in message
> news:edb90340.0311232036.e0eeae5@.posting.google.co m...
> > Can two entities have more than one relationship between them?
> > A(A_ID PK,..., bID FK)
> > B(B_ID PK,..., aID FK)
> > A.bID refers to B.B_ID
> > B.aID refers to A_ID
> > 2. Does it make sense?
> > Product (ProductID PK, Name,., SpecialAttrID FK)
> > Attribute (AttrID PK, Name,..,ProductID FK)
> > Product can have many attributes. One attribute belongs to only one
> product.
> > There is only one main("special") attribute for each product
> > Thank you in advance,
> > Andy|||"Andy" <net__space@.hotmail.com> wrote in message <news:edb90340.0311232036.e0eeae5@.posting.google.co m>...

> Can two entities have more than one relationship between them?
> A(A_ID PK,..., bID FK)
> B(B_ID PK,..., aID FK)
> A.bID refers to B.B_ID
> B.aID refers to A_ID
> 2. Does it make sense?
> Product (ProductID PK, Name,., SpecialAttrID FK)
> Attribute (AttrID PK, Name,..,ProductID FK)
> Product can have many attributes. One attribute belongs to only one product.
> There is only one main("special") attribute for each product

Maybe you really want an "extender table" approach, in which
the Product table holds attributes which all products have,
and additional tables to hold attributes which some, but not
all, products have, perhaps like so:

Product (ProductID PK, Name, Manufacturer, Price, Mass, Volume, ...)

Book (ProductID PK/FK, Author, Pages, Binding, ...)

Album (ProductID PK/FK, Artist, Tracks, Media, PlayingTime, ...)

Software (ProductID PK/FK, Platform, Media, ...)

--
Joe Foster <mailto:jlfoster%40znet.com> "Regged" again? <http://www.xenu.net/>
WARNING: I cannot be held responsible for the above They're coming to
because my cats have apparently learned to type. take me away, ha ha!|||raghuraman_ace@.rediffmail.com (Raghuraman) wrote in message news:<66c7bef8.0311240532.731c4819@.posting.google.com>...
> Hi,
> I think i does'nt make sence.
> The reason is for the creation of each table , another table should
> exists already vice-versa.
> So i think u can not create even a single table as that regard.
>
>
> With thanks

It is still not unusual for two tables to cross with a foreign key in
each pointing to the other. Circular relationships are not rare. As
another example,
a table of a publishers books can be linked with a table of the
publishers authors (books have authors and authors write books).

They can be murder to load (chicken or egg type question) and maintain
(deletes have the same problem), but they are not unusual.|||Whilst you can techincally create references this way (circular), I
would recommend not doing so. With a small and simple system, this
approach appears to be a good idea, however, I would suggest this is
bad practice as when you work on larger systems the complexity
increases dramatically. Don't get into the habit of doing this if you
can.

Our old back office system at work (pre me) was built with the
majority of references being circular. There were even tables which
held information on which circular link was to be used (depending on
the data). At the size of db we work with, this was a complete
nightmare. It was one of the worst designed systems I have ever seen.
Everyone on this forum would laugh if they saw the design. We have
since changed this as you would expect.

Yes, you can work with them, just explain to your colleagues why you
will be found mumbling to yourself later when it's become too complex.
If you absolutely have to do this, FFS make sure it's documented for
future developers.

Keep it simple. It will make a huge difference in the long run ! I'd
recommend spending a little longer working out an easier none circular
way of referencing the data.

That's my tuppence. You may well disagree.

"Joe \"Nuke Me Xemu\" Foster" <joe@.bftsi0.UUCP> wrote in message news:<1069701707.142710@.news-1.nethere.net>...
> "Andy" <net__space@.hotmail.com> wrote in message <news:edb90340.0311232036.e0eeae5@.posting.google.co m>...
> > Can two entities have more than one relationship between them?
> > A(A_ID PK,..., bID FK)
> > B(B_ID PK,..., aID FK)
> > A.bID refers to B.B_ID
> > B.aID refers to A_ID
> > 2. Does it make sense?
> > Product (ProductID PK, Name,., SpecialAttrID FK)
> > Attribute (AttrID PK, Name,..,ProductID FK)
> > Product can have many attributes. One attribute belongs to only one product.
> > There is only one main("special") attribute for each product
> Maybe you really want an "extender table" approach, in which
> the Product table holds attributes which all products have,
> and additional tables to hold attributes which some, but not
> all, products have, perhaps like so:
> Product (ProductID PK, Name, Manufacturer, Price, Mass, Volume, ...)
> Book (ProductID PK/FK, Author, Pages, Binding, ...)
> Album (ProductID PK/FK, Artist, Tracks, Media, PlayingTime, ...)
> Software (ProductID PK/FK, Platform, Media, ...)|||In article <edb90340.0311232036.e0eeae5@.posting.google.com>,
net__space@.hotmail.com says...
> Can two entities have more than one relationship between them?

There can be many individual relationships between tables. However, the
question is, does your design require it?

> 2. Does it make sense?
> Product (ProductID PK, Name,?, SpecialAttrID FK)
> Attribute (AttrID PK, Name,?.,ProductID FK)
> Product can have many attributes. One attribute belongs to only one product.
> There is only one main("special") attribute for each product

I would think that what you might want could be satisfied with a simple
one-to-many:

CREATE TABLE Product (
ProductID int NOT NULL,
ProductName varchar(18) NULL,
CONSTRAINT PK1 PRIMARY KEY CLUSTERED (ProductID)
)

CREATE TABLE Attribute (
AtrributeID int NOT NULL,
ProductID int NOT NULL,
AttributeName varchar(18) NULL,
MainAttribute bit NULL,
CONSTRAINT PK2 PRIMARY KEY CLUSTERED (AtrributeID),
FOREIGN KEY (ProductID)
REFERENCES Product(ProductID)
)

Other appropriate constraints (depending on your target platform) would
limit one MainAttribute being "true" within a set of attributes for one
given product.

Alternatively, does one attribute (guessing something like "height")
really only occur for one product or many? You might have a many-to-many
relationship here. It might be that you need three tables, with one
being an associative table between Product and Attribute:

CREATE TABLE Attribute(
AtrributeID int NOT NULL,
AttributeName varchar(18) NULL,
CONSTRAINT PK2 PRIMARY KEY CLUSTERED (AtrributeID)
)

CREATE TABLE Product(
ProductID int NOT NULL,
ProductName varchar(18) NULL,
CONSTRAINT PK1 PRIMARY KEY CLUSTERED (ProductID)
)

CREATE TABLE ProductAttribute(
ProductID int NOT NULL,
AtrributeID int NOT NULL,
MainAttribute bit NULL,
CONSTRAINT PKProductAttribute
PRIMARY KEY NONCLUSTERED (ProductID, AtrributeID),
FOREIGN KEY (ProductID)
REFERENCES Product(ProductID),
FOREIGN KEY (AtrributeID)
REFERENCES Attribute(AtrributeID)
)

These are some alternatives for you to consider.

------------
Paul Tiseo, Systems Programmer
Research Computing Facility, Mayo Clinic
tiseo128.paul23@.mayo.edu
(please remove numbers to email me)