diff --git a/tablefield.module b/tablefield.module
index 5b9d27f..98065f3 100644
--- a/tablefield.module
+++ b/tablefield.module
@@ -107,7 +107,7 @@ function tablefield_export_csv($entity_type, $entity_id, $field_name, $langcode,
   // Ensure that the data is available and that we can load a
   // temporary file to stream the data.
   if (isset($entity->{$field_name}[$langcode][$delta]['value']) && $fp = fopen($uri, 'w+')) {
-    $table = unserialize($entity->{$field_name}[$langcode][$delta]['value']);
+    $table = tablefield_unserialize($entity->{$field_name}[$langcode][$delta]['value']);
     // Save the data as a CSV file.
     foreach ($table['tabledata'] as $row) {
       // Remove the weight column.
@@ -305,6 +305,40 @@ function tablefield_field_widget_settings_form($field, $instance) {
 }
 
 /**
+ * Provides list of storage format options based on database capability.
+ */
+function tablefield_field_backend_storage_options() {
+  // Only provide PHP serialize if the database does not provide JSON column type.
+  $backend_options = array(
+    'serialize' => 'Serialized (PHP)',
+  );
+  // Get the connection object for the specified database key and target.
+  $conn = Database::getConnection();
+
+  switch ($conn->databaseType()) {
+  case 'mysql':
+    if (version_compare(mysql_get_client_info(), '5.7', '>=')) {
+      $backend_options = array(
+        'serialize' => 'Serialized (PHP)',
+        'json' => 'JSON',
+      );
+    }
+    break;
+
+  case 'pgsql':
+    $v = pg_version();
+    if (version_compare( $v['client'], '9.2', '>=')) {
+      $backend_options = array(
+        'serialize' => 'Serialized (PHP)',
+        'json' => 'JSON',
+      );
+    }
+    break;
+  }
+  return $backend_options;
+}
+
+/**
  * Implements hook_field_settings_form().
  */
 function tablefield_field_settings_form($field, $instance, $has_data) {
@@ -324,6 +358,16 @@ function tablefield_field_settings_form($field, $instance, $has_data) {
     '#markup' => t('If multiple values are allowed it is recommended to install and enable the !multiple_fields_remove_button_module. Additional TableField settings are available at !manage_display.', array('!multiple_fields_remove_button_module' => $multiple_fields_remove_button_module, '!manage_display' => $manage_display)),
     '#weight' => -100,
   );
+  
+  $backend_options = tablefield_field_backend_storage_options();
+  $form['backend_storage_format'] = array(
+    '#type' => 'select',
+    '#title' => t('Table Backend Storage in Database'),
+    '#options' => $backend_options,
+    '#size' => 1,
+    '#default_value' => isset($field['settings']['backend_storage_format']) ? $field['settings']['backend_storage_format'] : 'serialize',
+    '#description' => t('Select the separator for the CSV import/export.'),
+  );
 
   return $form;
 }
@@ -459,11 +503,11 @@ function tablefield_field_presave($entity_type, $entity, $field, $instance, $lan
         // Add the non-value data back in before we save.
         $tablefield = array_merge($tablefield, $table);
       }
-      $items[$delta]['value'] = isset($tablefield['tablefield']) ? serialize($tablefield['tablefield']) : '';
+      $items[$delta]['value'] = isset($tablefield['tablefield']) ? tablefield_serialize($tablefield['tablefield']) : '';
     }
     elseif (empty($table['tablefield'])) {
       // Batch processing only provides the 'value'.
-      $items[$delta]['tablefield'] = unserialize($items[$delta]['value']);
+      $items[$delta]['tablefield'] = tablefield_unserialize($items[$delta]['value']);
     }
   }
 }
@@ -496,7 +540,7 @@ function tablefield_field_load($entity_type, $entities, $field, $instances, $lan
   foreach ($entities as $id => $entity) {
     foreach ($items[$id] as $delta => $item) {
       if (isset($item['value'])) {
-        $items[$id][$delta]['tabledata'] = unserialize($item['value']);
+        $items[$id][$delta]['tabledata'] = tablefield_unserialize($item['value']);
       }
     }
   }
@@ -847,7 +891,7 @@ function tablefield_field_formatter_view($entity_type, $entity, $field, $instanc
       case 'format_raw':
         $values = array();
         foreach ($items as $delta => $table) {
-          $value = unserialize($table['value']);
+          $value = tablefield_unserialize($table['value']);
           // Swap rows and columns if the header is vertical (first column).
           if ($settings['vertheader']) {
             $transposed = tablefield_transpose($value['tabledata']);
@@ -1085,7 +1129,7 @@ function tablefield_field_formatter_view($entity_type, $entity, $field, $instanc
       default:
         foreach ($items as $delta => $table) {
           // Check for table caption.
-          $raw = unserialize($table['value']);
+          $raw = tablefield_unserialize($table['value']);
           $caption = isset($raw['caption']) ? check_plain($raw['caption']) : '';
 
           // Rationalize the stored data.
@@ -1093,7 +1137,7 @@ function tablefield_field_formatter_view($entity_type, $entity, $field, $instanc
             $tabledata = $table['tablefield'];
           }
           elseif (!empty($table['value'])) {
-            $tabledata = unserialize($table['value']);
+            $tabledata = tablefield_unserialize($table['value']);
           }
 
           // Run the table through input filters.
@@ -1297,7 +1341,7 @@ function tablefield_field_widget_form(&$form, &$form_state, $field, $instance, $
       $default_value = $items[$delta]['tablefield'];
     }
     elseif (isset($items[$delta]['value'])) {
-      $default_value = unserialize($items[$delta]['value']);
+      $default_value = tablefield_unserialize($items[$delta]['value']);
     }
     // If still nothing then get the instance default, but only for delta 0.
     elseif ($delta === 0 && isset($instance['default_value'][0]['tablefield'])) {
@@ -1480,7 +1524,7 @@ function tablefield_field_widget_form(&$form, &$form_state, $field, $instance, $
     '#description' => t('This brief caption will be associated with the table and will help Assitive Technology, like screen readers, better describe the content within.'),
   );
   if (isset($items[$delta]['value'])) {
-    $raw = unserialize($items[$delta]['value']);
+    $raw = tablefield_unserialize($items[$delta]['value']);
     if (isset($raw['caption'])) {
       $element['tablefield']['caption']['#default_value'] = check_plain($raw['caption']);
     }
@@ -2158,7 +2202,6 @@ function tablefield_form_alter(&$form, &$form_state, $form_id) {
     }
   }
 }
-
 /**
  * Returns HTML for a table. Based on the core function theme_table().
  *
@@ -2421,3 +2464,89 @@ function array_to_xml($data, &$xml_data) {
     }
   }
 }
+
+/**
+ * Helper function to serialize data for storage.
+ */
+function tablefield_serialize($field, $data) {
+  $backend_storage_format = isset($field['settings']['backend_storage_format']) ? $field['settings']['backend_storage_format'] : 'serialize';
+  switch ($backend_storage_format) {
+    case 'json':
+    $serialized = json_encode($data);
+    break;
+    
+    case 'serialize':
+    default:
+    $serialized = serialize($data);
+    break;
+  }
+  return $serialized;
+}
+
+/**
+ * Helper function to unserialize data for storage.
+ */
+function tablefield_unserialize($field, $data) {
+  switch ($field['settings']['backend_storage_format']) {
+    case 'json':
+    $unserialized = json_decode($data);
+    break;
+    
+    case 'serialize':
+    default:
+    $unserialized = unserialize($data);
+    break;
+  }
+  return $unserialized;
+}
+
+/**
+ * Implements hook_field_update_field().
+ *
+ */
+function tablefield_field_update_field($field, $prior_field, $has_data){
+  dpm($prior_field,'prior_field');
+  dpm($field,'field');
+  dpm($has_data,'has_data');
+  if ($has_data and $prior_field['settings']['backend_storage_format'] and ($prior_field['settings']['backend_storage_format'] <> $field['settings']['backend_storage_format']) ) {
+    // must update the data
+   tablefield_switch_data_format($field, $prior_field);
+  } else {
+    drupal_set_message('No data or backend_storage_format undefined - will not update');
+  }
+}
+
+function tablefield_switch_data_format($field, $prior_field){
+  // Change the default field for each content type.
+  return;
+  // Change all existing fields to store the data with the new format.
+  $field_name = $instance['field_name'];
+  foreach ($field['storage']['details']['sql'] as $revkey => $entry) {
+    foreach ($entry as $table => $columns) {
+      if (db_table_exists($table)) {
+        // must check for table as revision table may not be enabled
+        $field = $columns['value'];
+        $query = db_select($table, 'n')
+          ->fields('n')
+          ->execute()
+          ->fetchAll();
+        foreach ($query as $record) {
+          $instance = unserialize($record->$field);
+          // Change the stored data by a per record unique column key combination.
+          db_update($table)
+            ->fields(array(
+              $field => serialize($instance),
+            ))
+            ->condition('entity_id', $record->entity_id)
+            ->condition('revision_id', $record->revision_id)
+            ->condition('delta', $record->delta)
+            ->condition('entity_type', $record->entity_type)
+            ->condition('bundle', $record->bundle)
+            ->execute();
+        }
+      }
+    }
+  }
+  field_cache_clear();
+  drupal_set_message(t('All Table Field fields are now stored with a new data format.'), 'warning');
+}
