diff --git a/content.module b/content.module
index 81722db..d970ddf 100644
--- a/content.module
+++ b/content.module
@@ -176,8 +176,10 @@ function content_load(&$node) {
   $cid = 'content:'. $node->nid .':'. $node->vid;
   if ($cached = cache_get($cid, 'cache_content')) {
     $extra = unserialize($cached->data);
-    foreach ($extra as $key => $value) {
-      $node->$key = $value;
+    if ($extra) {
+      foreach ($extra as $key => $value) {
+        $node->$key = $value;
+      }
     }
     return $extra;
   }
@@ -542,28 +544,52 @@ function content_storage($op, $node) {
       $selects = array();
       foreach ($type['fields'] as $field) {
         $db_info = content_database_info($field);
+        $table = $db_info['table'];
         if ($field['multiple']) {
-          $selects[$db_info['table']]['multiple'] = TRUE;
+          $table_name = $table;
+          $selects[$table_name]['table_name'] = $table_name;
+          $selects[$table_name]['multiple'] = TRUE;
+        }
+        else if (!isset($primary_table) || count($selects[$primary_table]['join']) > 30) {
+          $table_name = $primary_table = $table;
+          $selects[$table_name]['table_name'] = $table_name;
+        }
+        else {
+          $table_name = $primary_table;
+          if ($table != $primary_table && (empty($selects[$primary_table]['join']) || !in_array($table, $selects[$primary_table]['join']))) {
+            $selects[$primary_table]['join'][] = $table;
+          }
         }
+
         foreach ($db_info['columns'] as $column => $attributes) {
-          $selects[$db_info['table']]['columns'][] = $attributes['column'];
+          // We should never multiple fields as the same name on different
+          // shared tables, but if we do, an alias for the field will need
+          // to be added.
+          $selects[$table_name]['columns'][] = $table .'.'. $attributes['column'];
+          $field['table'] = $table;
           $field['columns'][$column] = $attributes['column'];
         }
-        $selects[$db_info['table']]['fields'][] = $field;
+        $selects[$table_name]['fields'][] = $field;
       }
 
       foreach ($selects as $table => $select) {
         if ($select['multiple']) {
-          $select['columns'][] = 'delta';
+          $select['columns'][] = $select['table_name'] .'.delta';
+        }
+
+        $join = '';
+        if (!empty($select['join'])) {
+          content_storage_format_join($select['table_name'], TRUE);
+          $join = ' '. implode(' ', array_map('content_storage_format_join', $select['join']));
         }
-        $sql = 'SELECT '. implode(', ', $select['columns']) .' FROM {'. $table .'} WHERE vid = %d';
+
+        $sql = 'SELECT '. implode(', ', $select['columns']) .' FROM {'. $table .'} '. $select['table_name'] . $join .' WHERE '. $select['table_name'] .'.vid = %d';
         if ($select['multiple']) {
-          $result = db_query($sql .' ORDER BY delta', $node->vid);
+          $result = db_query($sql .' ORDER BY delta ASC', $node->vid);
         }
         else {
           $result = db_query_range($sql, $node->vid, 0, 1);
         }
-
         while ($row = db_fetch_array($result)) {
           foreach ($select['fields'] as $field) {
             if ($select['multiple']) {
@@ -722,6 +748,18 @@ function content_storage($op, $node) {
 }
 
 /**
+ * Format the joining of the shared tables
+ */
+function content_storage_format_join($a, $init = FALSE) {
+  static $table_name = '';
+  if ($init) {
+    $table_name = $a;
+  }
+  return 'LEFT JOIN {'. $a .'} '. $a .' ON '. $table_name .'.vid = '. $a
+  .'.vid';
+}
+
+/**
  *
  */
 function content_type_placeholder($type) {
diff --git a/content_admin.inc b/content_admin.inc
index 8e16889..10322cf 100644
--- a/content_admin.inc
+++ b/content_admin.inc
@@ -1016,35 +1016,6 @@ function content_alter_schema($previous_field, $new_field) {
 }
 
 /**
- * Content Schema Alter
- *
- * Alter the database schema.
- *
- * TODO figure out an API-safe way to use batching to update the nodes that
- * will be affected by this change so the node_save() hooks will fire.
- *
- */
-function content_alter_schema($previous_field, $new_field) {
-  $type = !empty($new_field) ? $new_field['type'] : $previous_field['type'];
-  $field_types = _content_field_types();
-  $field_type = $field_types[$type];
-  if (empty($previous_field)) {
-    $previous_columns = array();
-  }
-  else {
-    $previous_columns = module_invoke($field_type['module'], 'field_settings', 'database columns', $previous_field);
-  }
-  if (empty($new_field)) {
-    $new_columns = array();
-  }
-  else {
-    $new_columns = module_invoke($field_type['module'], 'field_settings', 'database columns', $new_field);
-  }
-
-  content_alter_db_field($previous_field, $previous_columns, $new_field, $new_columns);
-}
-
-/**
  * Perform adds, alters, and drops as needed to synchronize the database with
  * new field definitions.
  */
diff --git a/content_crud.inc b/content_crud.inc
index b971e50..7da55bc 100644
--- a/content_crud.inc
+++ b/content_crud.inc
@@ -1,5 +1,5 @@
 <?php
-// $Id$
+// $Id: content_crud.inc,v 1.4.2.11 2007/01/26 12:34:56 karens Exp $
 
 /**
  * @file
@@ -261,10 +261,6 @@ function content_field_instance_create($field) {
     $prev_field['db_storage'] = CONTENT_DB_STORAGE_PER_FIELD;
   }
 
-  $previous_fields = content_field_instance_read(array('field_name' => $field['field_name']));
-  $previous_field = array_pop($previous_fields);
-  $previous_field['db_storage'] = $field['db_storage'];
-
   // Invoke hook_content_fieldapi().
   module_invoke_all('content_fieldapi', 'create instance', $field);
 
@@ -272,7 +268,7 @@ function content_field_instance_create($field) {
   _content_field_write($field, 'update');
   _content_field_instance_write($field, 'create');
 
-  content_alter_schema(!empty($previous_field) ? $previous_field : array(), $field);
+  content_alter_schema(empty($prev_field['widget']) ? array() : $prev_field, $field);
 
   content_clear_type_cache(TRUE);
   menu_rebuild(TRUE);
