Magento Database - Missing primary keys for some tables - Issue? - database

Today I found that some database tables in my Magento 1.9.0.1 installation don't have primary keys. I found out during a search and replace in the database.
Are the primary keys important to run Magento properly? If so, how do I add them to the tables? I've checked out the Magento Database Repair Tool, however that only fixed foreign keys, not primary keys.
Any thoughts?
Thanks.
Missing primary keys:
The table "api_session" has no primary key. Changes will have to be made manually.
The table "catalog_category_anc_categs_index_idx" has no primary key. Changes will have to be made manually.
The table "catalog_category_anc_categs_index_tmp" has no primary key. Changes will have to be made manually.
The table "catalog_category_anc_products_index_idx" has no primary key. Changes will have to be made manually.
The table "catalog_category_anc_products_index_tmp" has no primary key. Changes will have to be made manually.
The table "catalog_category_product_index_enbl_idx" has no primary key. Changes will have to be made manually.
The table "catalog_category_product_index_enbl_tmp" has no primary key. Changes will have to be made manually.
The table "catalog_category_product_index_idx" has no primary key. Changes will have to be made manually.
The table "catalog_category_product_index_tmp" has no primary key. Changes will have to be made manually.
The table "log_url" has no primary key. Changes will have to be made manually.
The table "shipment_carriers" has no primary key. Changes will have to be made manually.
The table "shipment_export" has no primary key. Changes will have to be made manually.
The table "weee_discount" has no primary key. Changes will have to be made manually.

The following table in your list should have a primary key:
log_url
The following tables are not in out of the box Magento:
shipment_carriers
shipment_export
The rest of the tables do not have primary keys. This is okay, not all tables need to have primary keys, for example tables that join two tables or temporary tables. All the index tables are temporary and get cleared out pretty frequently, therefore no primary key needed.

Related

Handle primary key - foreign key tables insertion?

Suppose I have two tables (primary key -> foreign key) where one record in primary key table corresponds to many record in foreign key, so if I want to make insert page (using ASP.NET for instance) for both primary key table and foreign key table, how can I get the primary key value to insert it into the foreign key table?
(usually I took the max(of PK) but I am curious to find better solution)
I assume you are using SQL Server, since you mention the use of ASP.NET. Using Max(PK) is not a good idea in a multi-user system because eventually you will end up getting an incorrect primary key value. There are also resource issues to consider. In general, this approach should be avoided.
There are several ways you can accomplish what you want to do. One way is to do your inserts via stored procedures. The stored procedure for creating the primary key row would return the Id value of the new row, which then can be used for inserting your foreign key rows. But don't use Max(PK Value). Use the SCOPE_IDENTITY() value. This assumes you are using an Identity type for your PK values. You don't state what you are actually using.

Table with no primary foreign key match

Is it possible to have a table in a database that has no primary foreign key match up?
The table will be holding file paths to particular files and directories that I want to upload which doesn't relate to any of the other tables in the database. Is this good practise or should all tables have a primary foreign key match up? If so should I create a separate database with just this table?
Every table should have a key but that doesn't mean it has to have a foreign key referencing it. The purpose of the key is to ensure that data is uniquely identifiable and guarantee that the expected set of dependencies is enforced.

changing the primary key value in SQL server 2005

I have a Table which has a Primary Key field which is not set to auto-increment.
I want to change one of these primary keys to something different.
The problem arises with the other tables relations. The thing is, the guy who built this system did not build relations in SQL Server, but rather manually coded some override in the program that uses it - a VB 6 program.
How would I update a Primary Key and all instances of the Primary Key in other databases? I have to manually look for the instances(although I do know they are in only two tables) of the Primary Key and change them, but how do I do that?
Even though the person who first created the tables didn't include foreign keys to them, you can add them now if foreign keys are honored in your tables. When you create the foreign keys, create them with ON UPDATE CASCADE option. This way, when you update your primary key, the related foreign keys will also be updated.
One thing I would suggest is using the query of:
select * from INFORMATION_SCHEMA.Columns where Column_Name = 'FieldID'
This queries the metadata to see all where that field exists, just in case there are more. Then, just write an update script to change the key, unfortunately its a manual process but being that the relationship is missing it will make scripting easier.

Meaning of Primary Key to Microsoft SQL Server 2008

What meaning does the concept of a primary key have to the database engine of SQL Server? I don't mean the clustered/nonclustered index created on the "ID" column, i mean the constraint object "primary key". Does it matter if it exists or not?
Alternatives:
alter table add primary key clustered
alter table create clustered index
Does it make a difference?
In general, a KEY is a column (or combination of columns) that uniquely identifies each row in the table. It is possible to have multiple KEYs in a table (for example, you might have a Person table where both the social security number as well as an auto-increasing number are both KEYs).
The database designer chooses one of theses KEYs to be the PRIMARY KEY. Conceptually, it does not matter which KEY is chosen as the PRIMARY KEY. However, since the PRIMARY KEY is usually used to refer to entries in this table from other tables (through FOREIGN KEYs), choosing a good PRIMARY KEY can be relevant w.r.t. (a) performance and (b) maintainability:
(a) Since the primary key will usually be used in JOINs, the index on the primary key (its size, its distribution, ...) is much more relevant to performance than other indexes.
(b) Since the primary key is used as a foreign key in other tables, changing the primary key value is always a hassle, since all the foreign key values in the other tables need to be modified as well.
A PRIMARY KEY is a constraint - this is a logical object that says something about the rules that your data must adhere to. An index is an access structure - it says something about the way the machine can search through the data. To implement a PRIMARY KEY, most RDBMS-es use an index.
Some RDBMS-es (fe. MySQL) do not make the distinction between PRIMARY KEY or UNIQUE constraint and the index that is used to help implement it. But for example, Oracle does: in oracle you can do something like: ALTER TABLE t DROP pk KEEP INDEX. This is useful if you want to change the definition of the primary key (for example, you are replacing a natural primary key with a surrogate primary key) but you still want to have a unique constraint on the original primary key columns without rebuilding the index. That makes sense if the index is very large and would take considerable table and resources to rebuild.
From what I can see, MS SQL does not make the distinction. I mean a tool like Management studio does display "Keys", "Indexes" and "Constraints" in differrent folders, but changing the name of one immediately changes the name of the corresponding objects in the other folders. So I think here the distinction is not really present in this case.

Does a foreign key automatically create an index?

I've been told that if I foreign key two tables, that SQL Server will create something akin to an index in the child table. I have a hard time believing this to be true, but can't find much out there related specifically to this.
My real reason for asking this is because we're experiencing some very slow response time in a delete statement against a table that has probably 15 related tables. I've asked our database guy and he says that if there is a foreign key on the fields, then it acts like an index. What is your experience with this? Should I add indexes on all foreign key fields or are they just unnecessary overhead?
A foreign key is a constraint, a relationship between two tables - that has nothing to do with an index per se.
However, it makes a lot of sense to index all the columns that are part of any foreign key relationship. An FK-relationship will often need to look up a relating table and extract certain rows based on a single value or a range of values.
So it makes good sense to index any columns involved in an FK, but an FK per se is not an index.
Check out Kimberly Tripp's excellent article "When did SQL Server stop putting indexes on Foreign Key columns?".
Wow, the answers are all over the map. So the Documentation says:
A FOREIGN KEY constraint is a candidate for an index because:
Changes to PRIMARY KEY constraints are checked with FOREIGN KEY constraints in related tables.
Foreign key columns are often used in join criteria when the data from related tables is combined in queries by matching the column(s) in the FOREIGN KEY constraint of one table with the primary or unique key column(s) in the other table. An index allows Microsoft® SQL Server™ 2000 to find related data in the foreign key table quickly. However, creating this index is not a requirement. Data from two related tables can be combined even if no PRIMARY KEY or FOREIGN KEY constraints are defined between the tables, but a foreign key relationship between two tables indicates that the two tables have been optimized to be combined in a query that uses the keys as its criteria.
So it seems pretty clear (although the documentation is a bit muddled) that it does not in fact create an index.
No, there is no implicit index on foreign key fields, otherwise why would Microsoft say "Creating an index on a foreign key is often useful". Your colleague may be confusing the foreign key field in the referring table with the primary key in the referred-to table - primary keys do create an implicit index.
Foreign keys do not create indexes. Only alternate key constraints(UNIQUE) and primary key constraints create indexes. This is true in Oracle and SQL Server.
In PostgeSql you can check for indexes yourself if you hit \d tablename
You will see that btree indexes have been automatically created on columns with primary key and unique constraints, but not on columns with foreign keys.
I think that answers your question at least for postgres.
Say you have a big table called orders, and a small table called customers. There is a foreign key from an order to a customer. Now if you delete a customer, Sql Server must check that there are no orphan orders; if there are, it raises an error.
To check if there are any orders, Sql Server has to search the big orders table. Now if there is an index, the search will be fast; if there is not, the search will be slow.
So in this case, the slow delete could be explained by the absence of an index. Especially if Sql Server would have to search 15 big tables without an index.
P.S. If the foreign key has ON DELETE CASCADE, Sql Server still has to search the order table, but then to remove any orders that reference the deleted customer.
SQL Server autocreates indices for Primary Keys, but not for Foreign Keys. Create the index for the Foreign Keys. It's probably worth the overhead.
It depends. On MySQL an index is created if you don't create it on your own:
MySQL requires that foreign key columns be indexed; if you create a table with a foreign key constraint but no index on a given column, an index is created.
Source: https://dev.mysql.com/doc/refman/8.0/en/constraint-foreign-key.html
The same for MySQL 5.6 eh.
Strictly speaking, foreign keys have absolutely nothing to do with indexes, yes. But, as the speakers above me pointed out, it makes sense to create one to speed up the FK-lookups. In fact, in MySQL, if you don't specify an index in your FK declaration, the engine (InnoDB) creates it for you automatically.
Not to my knowledge. A foreign key only adds a constraint that the value in the child key also be represented somewhere in the parent column. It's not telling the database that the child key also needs to be indexed, only constrained.
I notice that Entity Framework 6.1 pointed at MSSQL does automatically add indexes on foreign keys.

Resources