diff --git a/core/config/schema/core.data_types.schema.yml b/core/config/schema/core.data_types.schema.yml
index cc89fa9..4968087 100644
--- a/core/config/schema/core.data_types.schema.yml
+++ b/core/config/schema/core.data_types.schema.yml
@@ -445,6 +445,9 @@ field.storage_settings.string:
     case_sensitive:
       type: boolean
       label: 'Case sensitive'
+    is_ascii:
+      type: boolean
+      label: 'Contains US ASCII characters only'
 
 field.field_settings.string:
   type: mapping
diff --git a/core/lib/Drupal/Core/Cache/DatabaseBackend.php b/core/lib/Drupal/Core/Cache/DatabaseBackend.php
index b1144e4..267c1de 100644
--- a/core/lib/Drupal/Core/Cache/DatabaseBackend.php
+++ b/core/lib/Drupal/Core/Cache/DatabaseBackend.php
@@ -443,6 +443,7 @@ public function schemaDefinition() {
           'description' => 'Primary Key: Unique cache ID.',
           'type' => 'varchar',
           'length' => 255,
+          'is_ascii' => TRUE,
           'not null' => TRUE,
           'default' => '',
           'binary' => TRUE,
@@ -483,6 +484,7 @@ public function schemaDefinition() {
         'checksum' => array(
           'description' => 'The tag invalidation checksum when this entry was saved.',
           'type' => 'varchar',
+          'is_ascii' => TRUE,
           'length' => 255,
           'not null' => TRUE,
         ),
diff --git a/core/lib/Drupal/Core/Cache/DatabaseCacheTagsChecksum.php b/core/lib/Drupal/Core/Cache/DatabaseCacheTagsChecksum.php
index cc882ee..59bb484 100644
--- a/core/lib/Drupal/Core/Cache/DatabaseCacheTagsChecksum.php
+++ b/core/lib/Drupal/Core/Cache/DatabaseCacheTagsChecksum.php
@@ -177,6 +177,7 @@ public function schemaDefinition() {
           'description' => 'Namespace-prefixed tag string.',
           'type' => 'varchar',
           'length' => 255,
+          'is_ascii' => TRUE,
           'not null' => TRUE,
           'default' => '',
         ),
diff --git a/core/lib/Drupal/Core/Config/DatabaseStorage.php b/core/lib/Drupal/Core/Config/DatabaseStorage.php
index 6c33273..e74c2ff 100644
--- a/core/lib/Drupal/Core/Config/DatabaseStorage.php
+++ b/core/lib/Drupal/Core/Config/DatabaseStorage.php
@@ -194,6 +194,7 @@ protected static function schemaDefinition() {
           'description' => 'Primary Key: Config object collection.',
           'type' => 'varchar',
           'length' => 255,
+          'is_ascii' => TRUE,
           'not null' => TRUE,
           'default' => '',
         ),
@@ -201,6 +202,7 @@ protected static function schemaDefinition() {
           'description' => 'Primary Key: Config object name.',
           'type' => 'varchar',
           'length' => 255,
+          'is_ascii' => TRUE,
           'not null' => TRUE,
           'default' => '',
         ),
diff --git a/core/lib/Drupal/Core/Database/Driver/mysql/Schema.php b/core/lib/Drupal/Core/Database/Driver/mysql/Schema.php
index d0aba49..e4183eb 100644
--- a/core/lib/Drupal/Core/Database/Driver/mysql/Schema.php
+++ b/core/lib/Drupal/Core/Database/Driver/mysql/Schema.php
@@ -144,6 +144,9 @@ protected function createFieldSql($name, $spec) {
       if (!empty($spec['binary'])) {
         $sql .= ' BINARY';
       }
+      if (!empty($spec['is_ascii'])) {
+        $sql .= ' CHARACTER SET ascii COLLATE ascii_general_ci';
+      }
     }
     elseif (isset($spec['precision']) && isset($spec['scale'])) {
       $sql .= '(' . $spec['precision'] . ', ' . $spec['scale'] . ')';
diff --git a/core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorageSchema.php b/core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorageSchema.php
index 6fb4ddf..fd2959f 100644
--- a/core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorageSchema.php
+++ b/core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorageSchema.php
@@ -1571,6 +1571,7 @@ protected function getDedicatedTableSchema(FieldStorageDefinitionInterface $stor
         'type' => 'varchar',
         'length' => 128,
         'not null' => TRUE,
+        'is_ascii' => TRUE,
         'description' => 'The entity id this data is attached to',
       );
     }
@@ -1603,6 +1604,7 @@ protected function getDedicatedTableSchema(FieldStorageDefinitionInterface $stor
         'bundle' => array(
           'type' => 'varchar',
           'length' => 128,
+          'is_ascii' => TRUE,
           'not null' => TRUE,
           'default' => '',
           'description' => 'The field instance bundle to which this row belongs, used when deleting a field instance',
@@ -1619,6 +1621,7 @@ protected function getDedicatedTableSchema(FieldStorageDefinitionInterface $stor
         'langcode' => array(
           'type' => 'varchar',
           'length' => 32,
+          'is_ascii' => TRUE,
           'not null' => TRUE,
           'default' => '',
           'description' => 'The language code for this data item.',
diff --git a/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/EntityReferenceItem.php b/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/EntityReferenceItem.php
index ca54aa8..91ccdd9 100644
--- a/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/EntityReferenceItem.php
+++ b/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/EntityReferenceItem.php
@@ -137,6 +137,7 @@ public static function schema(FieldStorageDefinitionInterface $field_definition)
           // If the target entities act as bundles for another entity type,
           // their IDs should not exceed the maximum length for bundles.
           'length' => $target_type_info->getBundleOf() ? EntityTypeInterface::BUNDLE_MAX_LENGTH : 255,
+          'is_ascii' => TRUE,
         ),
       );
     }
diff --git a/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/LanguageItem.php b/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/LanguageItem.php
index 9ab60a4..b7ce7fb 100644
--- a/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/LanguageItem.php
+++ b/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/LanguageItem.php
@@ -44,6 +44,7 @@ class LanguageItem extends FieldItemBase {
   public static function propertyDefinitions(FieldStorageDefinitionInterface $field_definition) {
     $properties['value'] = DataDefinition::create('string')
       ->setLabel(t('Language code'))
+      ->setSetting('is_ascii', TRUE)
       ->setRequired(TRUE);
 
     $properties['language'] = DataReferenceDefinition::create('language')
@@ -75,6 +76,7 @@ public static function schema(FieldStorageDefinitionInterface $field_definition)
         'value' => array(
           'type' => 'varchar',
           'length' => 12,
+          'is_ascii' => TRUE,
         ),
       ),
     );
diff --git a/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/StringItem.php b/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/StringItem.php
index 8817c87..12bb145 100644
--- a/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/StringItem.php
+++ b/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/StringItem.php
@@ -32,6 +32,7 @@ class StringItem extends StringItemBase {
   public static function defaultStorageSettings() {
     return array(
       'max_length' => 255,
+      'is_ascii' => FALSE,
     ) + parent::defaultStorageSettings();
   }
 
@@ -45,6 +46,7 @@ public static function schema(FieldStorageDefinitionInterface $field_definition)
           'type' => 'varchar',
           'length' => (int) $field_definition->getSetting('max_length'),
           'binary' => $field_definition->getSetting('case_sensitive'),
+          'is_ascii' => $field_definition->getSetting('is_ascii'),
         ),
       ),
     );
diff --git a/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/UuidItem.php b/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/UuidItem.php
index 84d1ec5..1bdd10e 100644
--- a/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/UuidItem.php
+++ b/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/UuidItem.php
@@ -30,6 +30,7 @@ class UuidItem extends StringItem {
   public static function defaultStorageSettings() {
     return array(
       'max_length' => 128,
+      'is_ascii' => TRUE,
     ) + parent::defaultStorageSettings();
   }
 
diff --git a/core/lib/Drupal/Core/Menu/MenuTreeStorage.php b/core/lib/Drupal/Core/Menu/MenuTreeStorage.php
index 2ce68f7..046e307 100644
--- a/core/lib/Drupal/Core/Menu/MenuTreeStorage.php
+++ b/core/lib/Drupal/Core/Menu/MenuTreeStorage.php
@@ -1195,6 +1195,7 @@ protected static function schemaDefinition() {
           'description' => "The menu name. All links with the same menu name (such as 'tools') are part of the same menu.",
           'type' => 'varchar',
           'length' => 32,
+          'is_ascii' => TRUE,
           'not null' => TRUE,
           'default' => '',
         ),
@@ -1208,6 +1209,7 @@ protected static function schemaDefinition() {
           'description' => 'Unique machine name: the plugin ID.',
           'type' => 'varchar',
           'length' => 255,
+          'is_ascii' => TRUE,
           'not null' => TRUE,
         ),
         'parent' => array(
@@ -1215,11 +1217,13 @@ protected static function schemaDefinition() {
           'type' => 'varchar',
           'length' => 255,
           'not null' => TRUE,
+          'is_ascii' => TRUE,
           'default' => '',
         ),
         'route_name' => array(
           'description' => 'The machine name of a defined Symfony Route this menu item represents.',
           'type' => 'varchar',
+          'is_ascii' => TRUE,
           'length' => 255,
         ),
         'route_param_key' => array(
@@ -1283,6 +1287,7 @@ protected static function schemaDefinition() {
           'description' => 'The name of the module that generated this link.',
           'type' => 'varchar',
           'length' => DRUPAL_EXTENSION_NAME_MAX_LENGTH,
+          'is_ascii' => TRUE,
           'not null' => TRUE,
           'default' => 'system',
         ),
diff --git a/core/modules/aggregator/src/Entity/Feed.php b/core/modules/aggregator/src/Entity/Feed.php
index 6f3d2e2..a5ed081 100644
--- a/core/modules/aggregator/src/Entity/Feed.php
+++ b/core/modules/aggregator/src/Entity/Feed.php
@@ -226,6 +226,7 @@ public static function baseFieldDefinitions(EntityTypeInterface $entity_type) {
 
     $fields['hash'] = BaseFieldDefinition::create('string')
       ->setLabel(t('Hash'))
+      ->setSetting('is_ascii', TRUE)
       ->setDescription(t('Calculated hash of the feed data, used for validating cache.'));
 
     $fields['etag'] = BaseFieldDefinition::create('string')
diff --git a/core/modules/aggregator/src/FeedInterface.php b/core/modules/aggregator/src/FeedInterface.php
index 29c6782..e678c90 100644
--- a/core/modules/aggregator/src/FeedInterface.php
+++ b/core/modules/aggregator/src/FeedInterface.php
@@ -170,7 +170,8 @@ public function getHash();
    * Sets the calculated hash of the feed data, used for validating cache.
    *
    * @param string $hash
-   *   A string containing the calculated hash of the feed.
+   *   A string containing the calculated hash of the feed. Must contain
+   *   US ASCII characters only.
    *
    * @return \Drupal\aggregator\FeedInterface
    *   The class instance that this method is called on.
diff --git a/core/modules/aggregator/src/ItemsImporter.php b/core/modules/aggregator/src/ItemsImporter.php
index 3098f08..1c1aaa2 100644
--- a/core/modules/aggregator/src/ItemsImporter.php
+++ b/core/modules/aggregator/src/ItemsImporter.php
@@ -9,6 +9,7 @@
 
 use Drupal\aggregator\Plugin\AggregatorPluginManager;
 use Drupal\Component\Plugin\Exception\PluginException;
+use Drupal\Component\Utility\Crypt;
 use Drupal\Core\Config\ConfigFactoryInterface;
 use Psr\Log\LoggerInterface;
 
@@ -113,7 +114,7 @@ public function refresh(FeedInterface $feed) {
     // We store the hash of feed data in the database. When refreshing a
     // feed we compare stored hash and new hash calculated from downloaded
     // data. If both are equal we say that feed is not updated.
-    $hash = hash('sha256', $feed->source_string);
+    $hash = Crypt::hashBase64('sha256', $feed->source_string);
     $has_new_content = $success && ($feed->getHash() != $hash);
 
     if ($has_new_content) {
diff --git a/core/modules/ban/ban.install b/core/modules/ban/ban.install
index 7a5494f..9955eb5 100644
--- a/core/modules/ban/ban.install
+++ b/core/modules/ban/ban.install
@@ -22,6 +22,7 @@ function ban_schema() {
         'description' => 'IP address',
         'type' => 'varchar',
         'length' => 40,
+        'is_ascii' => TRUE,
         'not null' => TRUE,
         'default' => '',
       ),
diff --git a/core/modules/comment/comment.install b/core/modules/comment/comment.install
index 64aa6bd..49b2edc 100644
--- a/core/modules/comment/comment.install
+++ b/core/modules/comment/comment.install
@@ -50,6 +50,7 @@ function comment_schema() {
         'not null' => TRUE,
         'default' => 'node',
         'length' => EntityTypeInterface::ID_MAX_LENGTH,
+        'is_ascii' => TRUE,
         'description' => 'The entity_type of the entity to which this comment is a reply.',
       ),
       'field_name' => array(
@@ -57,6 +58,7 @@ function comment_schema() {
         'not null' => TRUE,
         'default' => '',
         'length' => FieldStorageConfig::NAME_MAX_LENGTH,
+        'is_ascii' => TRUE,
         'description' => 'The field_name of the field that was used to add this comment.',
       ),
       'cid' => array(
diff --git a/core/modules/comment/src/Entity/Comment.php b/core/modules/comment/src/Entity/Comment.php
index 798a69f..f83f54b 100644
--- a/core/modules/comment/src/Entity/Comment.php
+++ b/core/modules/comment/src/Entity/Comment.php
@@ -303,6 +303,7 @@ public static function baseFieldDefinitions(EntityTypeInterface $entity_type) {
     $fields['entity_type'] = BaseFieldDefinition::create('string')
       ->setLabel(t('Entity type'))
       ->setDescription(t('The entity type to which this comment is attached.'))
+      ->setSetting('is_ascii', TRUE)
       ->setSetting('max_length', EntityTypeInterface::ID_MAX_LENGTH);
 
     $fields['comment_type'] = BaseFieldDefinition::create('entity_reference')
@@ -313,6 +314,7 @@ public static function baseFieldDefinitions(EntityTypeInterface $entity_type) {
     $fields['field_name'] = BaseFieldDefinition::create('string')
       ->setLabel(t('Comment field name'))
       ->setDescription(t('The field name through which this comment was added.'))
+      ->setSetting('is_ascii', TRUE)
       ->setSetting('max_length', FieldStorageConfig::NAME_MAX_LENGTH);
 
     return $fields;
diff --git a/core/modules/dblog/dblog.install b/core/modules/dblog/dblog.install
index b7454c1..594bbfe 100644
--- a/core/modules/dblog/dblog.install
+++ b/core/modules/dblog/dblog.install
@@ -29,6 +29,7 @@ function dblog_schema() {
         'length' => 64,
         'not null' => TRUE,
         'default' => '',
+        'is_ascii' => TRUE,
         'description' => 'Type of log message, for example "user" or "page not found."',
       ),
       'message' => array(
@@ -73,6 +74,7 @@ function dblog_schema() {
         'length' => 128,
         'not null' => TRUE,
         'default' => '',
+        'is_ascii' => TRUE,
         'description' => 'Hostname of the user who triggered the event.',
       ),
       'timestamp' => array(
diff --git a/core/modules/file/file.install b/core/modules/file/file.install
index 6e188c6..05458eb 100644
--- a/core/modules/file/file.install
+++ b/core/modules/file/file.install
@@ -22,6 +22,7 @@ function file_schema() {
         'description' => 'The name of the module that is using the file.',
         'type' => 'varchar',
         'length' => DRUPAL_EXTENSION_NAME_MAX_LENGTH,
+        'is_ascii' => TRUE,
         'not null' => TRUE,
         'default' => '',
       ),
@@ -29,12 +30,14 @@ function file_schema() {
         'description' => 'The name of the object type in which the file is used.',
         'type' => 'varchar',
         'length' => 64,
+        'is_ascii' => TRUE,
         'not null' => TRUE,
         'default' => '',
       ),
       'id' => array(
         'description' => 'The primary key of the object using the file.',
         'type' => 'varchar',
+        'is_ascii' => TRUE,
         'length' => 64,
         'not null' => TRUE,
         'default' => 0,
diff --git a/core/modules/file/src/Entity/File.php b/core/modules/file/src/Entity/File.php
index 42de0ae..ff38ab3 100644
--- a/core/modules/file/src/Entity/File.php
+++ b/core/modules/file/src/Entity/File.php
@@ -254,6 +254,7 @@ public static function baseFieldDefinitions(EntityTypeInterface $entity_type) {
 
     $fields['filemime'] = BaseFieldDefinition::create('string')
       ->setLabel(t('File MIME type'))
+      ->setSetting('is_ascii', TRUE)
       ->setDescription(t("The file's MIME type."));
 
     $fields['filesize'] = BaseFieldDefinition::create('integer')
diff --git a/core/modules/locale/locale.install b/core/modules/locale/locale.install
index 81aadf5..3a3d5bc 100644
--- a/core/modules/locale/locale.install
+++ b/core/modules/locale/locale.install
@@ -69,6 +69,7 @@ function locale_schema() {
       'context' => array(
         'type' => 'varchar',
         'length' => 255,
+        'is_ascii' => TRUE,
         'not null' => TRUE,
         'default' => '',
         'description' => 'The context this string applies to.',
@@ -76,6 +77,7 @@ function locale_schema() {
       'version' => array(
         'type' => 'varchar',
         'length' => 20,
+        'is_ascii' => TRUE,
         'not null' => TRUE,
         'default' => 'none',
         'description' => 'Version of Drupal where the string was last used (for locales optimization).',
@@ -105,6 +107,7 @@ function locale_schema() {
       'language' => array(
         'type' => 'varchar',
         'length' => 12,
+        'is_ascii' => TRUE,
         'not null' => TRUE,
         'default' => '',
         'description' => 'Language code. References {language}.langcode.',
@@ -144,6 +147,7 @@ function locale_schema() {
       'type' => array(
         'type' => 'varchar',
         'length' => 50,
+        'is_ascii' => TRUE,
         'not null' => TRUE,
         'default' => '',
         'description' => 'The location type (file, config, path, etc).',
@@ -158,6 +162,7 @@ function locale_schema() {
       'version' => array(
         'type' => 'varchar',
         'length' => 20,
+        'is_ascii' => TRUE,
         'not null' => TRUE,
         'default' => 'none',
         'description' => 'Version of Drupal where the location was found.',
@@ -183,6 +188,7 @@ function locale_schema() {
         'type' => 'varchar',
         'length' => '255',
         'not null' => TRUE,
+        'is_ascii' => TRUE,
         'default' => '',
         'description' => 'A unique short name to identify the project the file belongs to.',
       ),
@@ -190,6 +196,7 @@ function locale_schema() {
         'type' => 'varchar',
         'length' => '12',
         'not null' => TRUE,
+        'is_ascii' => TRUE,
         'default' => '',
         'description' => 'Language code of this translation. References {language}.langcode.',
       ),
diff --git a/core/modules/menu_link_content/src/Entity/MenuLinkContent.php b/core/modules/menu_link_content/src/Entity/MenuLinkContent.php
index 5570a2a..d6610a0 100644
--- a/core/modules/menu_link_content/src/Entity/MenuLinkContent.php
+++ b/core/modules/menu_link_content/src/Entity/MenuLinkContent.php
@@ -250,6 +250,7 @@ public static function baseFieldDefinitions(EntityTypeInterface $entity_type) {
       ->setLabel(t('Bundle'))
       ->setDescription(t('The content menu link bundle.'))
       ->setSetting('max_length', EntityTypeInterface::BUNDLE_MAX_LENGTH)
+      ->setSetting('is_ascii', TRUE)
       ->setReadOnly(TRUE);
 
     $fields['title'] = BaseFieldDefinition::create('string')
@@ -291,7 +292,8 @@ public static function baseFieldDefinitions(EntityTypeInterface $entity_type) {
     $fields['menu_name'] = BaseFieldDefinition::create('string')
       ->setLabel(t('Menu name'))
       ->setDescription(t('The menu name. All links with the same menu name (such as "tools") are part of the same menu.'))
-      ->setDefaultValue('tools');
+      ->setDefaultValue('tools')
+      ->setSetting('is_ascii', TRUE);
 
     $fields['link'] = BaseFieldDefinition::create('link')
       ->setLabel(t('Link'))
diff --git a/core/modules/node/node.install b/core/modules/node/node.install
index fa0d245..a4227ad 100644
--- a/core/modules/node/node.install
+++ b/core/modules/node/node.install
@@ -56,6 +56,7 @@ function node_schema() {
         'description' => 'The {language}.langcode of this node.',
         'type' => 'varchar',
         'length' => 12,
+        'is_ascii' => TRUE,
         'not null' => TRUE,
         'default' => '',
       ),
@@ -78,6 +79,7 @@ function node_schema() {
         'type' => 'varchar',
         'length' => 255,
         'not null' => TRUE,
+        'is_ascii' => TRUE,
         'default' => '',
       ),
       'grant_view' => array(
diff --git a/core/modules/search/search.install b/core/modules/search/search.install
index a298f2f..8b42d0c 100644
--- a/core/modules/search/search.install
+++ b/core/modules/search/search.install
@@ -22,6 +22,7 @@ function search_schema() {
       'langcode' => array(
         'type' => 'varchar',
         'length' => '12',
+        'is_ascii' => TRUE,
         'not null' => TRUE,
         'description' => 'The {languages}.langcode of the item variant.',
         'default' => '',
@@ -29,6 +30,7 @@ function search_schema() {
       'type' => array(
         'type' => 'varchar',
         'length' => 64,
+        'is_ascii' => TRUE,
         'not null' => TRUE,
         'description' => 'Type of item, e.g. node.',
       ),
@@ -69,6 +71,7 @@ function search_schema() {
       'langcode' => array(
         'type' => 'varchar',
         'length' => '12',
+        'is_ascii' => TRUE,
         'not null' => TRUE,
         'description' => 'The {languages}.langcode of the item variant.',
         'default' => '',
@@ -76,6 +79,7 @@ function search_schema() {
       'type' => array(
         'type' => 'varchar',
         'length' => 64,
+        'is_ascii' => TRUE,
         'not null' => TRUE,
         'description' => 'The {search_dataset}.type of the searchable item to which the word belongs.',
       ),
diff --git a/core/modules/shortcut/shortcut.install b/core/modules/shortcut/shortcut.install
index c1a6883..ea749a2 100644
--- a/core/modules/shortcut/shortcut.install
+++ b/core/modules/shortcut/shortcut.install
@@ -24,6 +24,7 @@ function shortcut_schema() {
         'length' => 32,
         'not null' => TRUE,
         'default' => '',
+        'is_ascii' => TRUE,
         'description' => "The {shortcut_set}.set_name that will be displayed for this user.",
       ),
     ),
diff --git a/core/modules/simpletest/simpletest.install b/core/modules/simpletest/simpletest.install
index 47c0ee2..474a605 100644
--- a/core/modules/simpletest/simpletest.install
+++ b/core/modules/simpletest/simpletest.install
@@ -110,6 +110,7 @@ function simpletest_schema() {
       'test_class' => array(
         'type' => 'varchar',
         'length' => 255,
+        'is_ascii' => TRUE,
         'not null' => TRUE,
         'default' => '',
         'description' => 'The name of the class that created this message.',
@@ -130,6 +131,7 @@ function simpletest_schema() {
         'type' => 'varchar',
         'length' => 255,
         'not null' => TRUE,
+        'is_ascii' => TRUE,
         'default' => '',
         'description' => 'The message group this message belongs to. For example: warning, browser, user.',
       ),
diff --git a/core/modules/system/database.api.php b/core/modules/system/database.api.php
index a01ff59..834baf3 100644
--- a/core/modules/system/database.api.php
+++ b/core/modules/system/database.api.php
@@ -293,6 +293,9 @@
  *       'varchar' or 'text' fields to use case-sensitive binary collation.
  *       This has no effect on other database types for which case sensitivity
  *       is already the default behavior.
+ *     - 'is_ascii': A boolean indicating that MySQL should use
+ *       ASCII character encoding for the field. This helps index usage be
+ *       more efficient, and should be used on machine name fields.
  *     All parameters apart from 'type' are optional except that type
  *     'numeric' columns must specify 'precision' and 'scale', and type
  *     'varchar' must specify the 'length' parameter.
diff --git a/core/modules/system/src/Tests/Database/SchemaTest.php b/core/modules/system/src/Tests/Database/SchemaTest.php
index a59b9d9..cb91621 100644
--- a/core/modules/system/src/Tests/Database/SchemaTest.php
+++ b/core/modules/system/src/Tests/Database/SchemaTest.php
@@ -49,6 +49,12 @@ function testSchema() {
           'default' => "'\"funky default'\"",
           'description' => 'Schema column description for string.',
         ),
+        'test_field_string_is_ascii'  => array(
+          'type' => 'varchar',
+          'length' => 255,
+          'is_ascii' => TRUE,
+          'description' => 'Schema column description for is_ascii string.',
+        ),
       ),
     );
     db_create_table('test_table', $table_specification);
@@ -62,6 +68,17 @@ function testSchema() {
     // Assert that the column comment has been set.
     $this->checkSchemaComment($table_specification['fields']['test_field']['description'], 'test_table', 'test_field');
 
+    // Make sure that varchar fields have the correct collation.
+    $columns = db_query('SHOW FULL COLUMNS FROM {test_table}');
+    foreach ($columns as $column) {
+      if ($column->Field == 'test_field_string') {
+        $this->assertTrue($column->Collation == 'utf8_general_ci');
+      }
+      if ($column->Field == 'test_field_string_is_ascii') {
+        $this->assertTrue($column->Collation == 'ascii_general_ci');
+      }
+    }
+
     // An insert without a value for the column 'test_table' should fail.
     $this->assertFalse($this->tryInsert(), 'Insert without a default failed.');
 
diff --git a/core/modules/system/system.install b/core/modules/system/system.install
index f1e6612..f531f3e 100644
--- a/core/modules/system/system.install
+++ b/core/modules/system/system.install
@@ -687,6 +687,7 @@ function system_schema() {
         'description' => "A string token generated against the current user's session id and the batch id, used to ensure that only the user who submitted the batch can effectively access it.",
         'type' => 'varchar',
         'length' => 64,
+        'is_ascii' => TRUE,
         'not null' => TRUE,
       ),
       'timestamp' => array(
@@ -719,6 +720,7 @@ function system_schema() {
         'description' => 'Name of event (e.g. contact).',
         'type' => 'varchar',
         'length' => 64,
+        'is_ascii' => TRUE,
         'not null' => TRUE,
         'default' => '',
       ),
@@ -726,6 +728,7 @@ function system_schema() {
         'description' => 'Identifier of the visitor, such as an IP address or hostname.',
         'type' => 'varchar',
         'length' => 128,
+        'is_ascii' => TRUE,
         'not null' => TRUE,
         'default' => '',
       ),
@@ -756,6 +759,7 @@ function system_schema() {
         'description' => 'A named collection of key and value pairs.',
         'type' => 'varchar',
         'length' => 128,
+        'is_ascii' => TRUE,
         'not null' => TRUE,
         'default' => '',
       ),
@@ -763,6 +767,7 @@ function system_schema() {
         'description' => 'The key of the key-value pair. As KEY is a SQL reserved keyword, name was chosen instead.',
         'type' => 'varchar',
         'length' => 128,
+        'is_ascii' => TRUE,
         'not null' => TRUE,
         'default' => '',
       ),
@@ -783,6 +788,7 @@ function system_schema() {
         'description' => 'A named collection of key and value pairs.',
         'type' => 'varchar',
         'length' => 128,
+        'is_ascii' => TRUE,
         'not null' => TRUE,
         'default' => '',
       ),
@@ -791,6 +797,7 @@ function system_schema() {
         'description' => 'The key of the key/value pair.',
         'type' => 'varchar',
         'length' => 128,
+        'is_ascii' => TRUE,
         'not null' => TRUE,
         'default' => '',
       ),
@@ -827,6 +834,7 @@ function system_schema() {
         'type' => 'varchar',
         'length' => 255,
         'not null' => TRUE,
+        'is_ascii' => TRUE,
         'default' => '',
         'description' => 'The queue name.',
       ),
@@ -864,6 +872,7 @@ function system_schema() {
         'description' => 'Primary Key: Machine name of this route',
         'type' => 'varchar',
         'length' => 255,
+        'is_ascii' => TRUE,
         'not null' => TRUE,
         'default' => '',
       ),
@@ -913,12 +922,14 @@ function system_schema() {
         'description' => 'Primary Key: Unique name.',
         'type' => 'varchar',
         'length' => 255,
+        'is_ascii' => TRUE,
         'not null' => TRUE,
         'default' => ''
       ),
       'value' => array(
         'description' => 'A value for the semaphore.',
         'type' => 'varchar',
+        'is_ascii' => TRUE,
         'length' => 255,
         'not null' => TRUE,
         'default' => ''
@@ -963,12 +974,14 @@ function system_schema() {
         'description' => "A session ID (hashed). The value is generated by Drupal's session handlers.",
         'type' => 'varchar',
         'length' => 128,
+        'is_ascii' => TRUE,
         'not null' => TRUE,
       ),
       'hostname' => array(
         'description' => 'The IP address that last used this session ID (sid).',
         'type' => 'varchar',
         'length' => 128,
+        'is_ascii' => TRUE,
         'not null' => TRUE,
         'default' => '',
       ),
@@ -1027,6 +1040,7 @@ function system_schema() {
         'description' => "The language code this alias is for; if 'und', the alias will be used for unknown languages. Each Drupal path can have an alias for each supported language.",
         'type' => 'varchar',
         'length' => 12,
+        'is_ascii' => TRUE,
         'not null' => TRUE,
         'default' => '',
       ),
diff --git a/core/modules/text/src/Plugin/Field/FieldType/TextLongItem.php b/core/modules/text/src/Plugin/Field/FieldType/TextLongItem.php
index c55953c..b1cc1c0 100644
--- a/core/modules/text/src/Plugin/Field/FieldType/TextLongItem.php
+++ b/core/modules/text/src/Plugin/Field/FieldType/TextLongItem.php
@@ -36,6 +36,7 @@ public static function schema(FieldStorageDefinitionInterface $field_definition)
         'format' => array(
           'type' => 'varchar',
           'length' => 255,
+          'is_ascii' => TRUE,
         ),
       ),
       'indexes' => array(
diff --git a/core/modules/text/src/Plugin/Field/FieldType/TextWithSummaryItem.php b/core/modules/text/src/Plugin/Field/FieldType/TextWithSummaryItem.php
index 48d4dac..ffefcef 100644
--- a/core/modules/text/src/Plugin/Field/FieldType/TextWithSummaryItem.php
+++ b/core/modules/text/src/Plugin/Field/FieldType/TextWithSummaryItem.php
@@ -70,6 +70,7 @@ public static function schema(FieldStorageDefinitionInterface $field_definition)
         'format' => array(
           'type' => 'varchar',
           'length' => 255,
+          'is_ascii' => TRUE,
         ),
       ),
       'indexes' => array(
diff --git a/core/modules/user/user.install b/core/modules/user/user.install
index 7b3c3d3..de2099b 100644
--- a/core/modules/user/user.install
+++ b/core/modules/user/user.install
@@ -23,6 +23,7 @@ function user_schema() {
         'description' => 'The name of the module declaring the variable.',
         'type' => 'varchar',
         'length' => DRUPAL_EXTENSION_NAME_MAX_LENGTH,
+        'is_ascii' => TRUE,
         'not null' => TRUE,
         'default' => '',
       ),
@@ -31,6 +32,7 @@ function user_schema() {
         'type' => 'varchar',
         'length' => 128,
         'not null' => TRUE,
+        'is_ascii' => TRUE,
         'default' => '',
       ),
       'value' => array(
diff --git a/core/tests/Drupal/Tests/Core/Entity/Sql/SqlContentEntityStorageSchemaTest.php b/core/tests/Drupal/Tests/Core/Entity/Sql/SqlContentEntityStorageSchemaTest.php
index 08f73cb..e9793aa 100644
--- a/core/tests/Drupal/Tests/Core/Entity/Sql/SqlContentEntityStorageSchemaTest.php
+++ b/core/tests/Drupal/Tests/Core/Entity/Sql/SqlContentEntityStorageSchemaTest.php
@@ -804,6 +804,7 @@ public function testDedicatedTableSchema() {
           'bundle' => array(
             'type' => 'varchar',
             'length' => 128,
+            'is_ascii' => true,
             'not null' => true,
             'default' => '',
             'description' => 'The field instance bundle to which this row belongs, used when deleting a field instance',
@@ -830,6 +831,7 @@ public function testDedicatedTableSchema() {
           'langcode' => array(
             'type' => 'varchar',
             'length' => 32,
+            'is_ascii' => true,
             'not null' => true,
             'default' => '',
             'description' => 'The language code for this data item.',
@@ -949,6 +951,7 @@ public function testDedicatedTableSchemaForEntityWithStringIdentifier() {
           'bundle' => array(
             'type' => 'varchar',
             'length' => 128,
+            'is_ascii' => true,
             'not null' => true,
             'default' => '',
             'description' => 'The field instance bundle to which this row belongs, used when deleting a field instance',
@@ -964,17 +967,20 @@ public function testDedicatedTableSchemaForEntityWithStringIdentifier() {
             'type' => 'varchar',
             'length' => 128,
             'not null' => true,
+            'is_ascii' => true,
             'description' => 'The entity id this data is attached to',
           ),
           'revision_id' => array(
             'type' => 'varchar',
             'length' => 128,
             'not null' => true,
+            'is_ascii' => true,
             'description' => 'The entity revision id this data is attached to, which for an unversioned entity type is the same as the entity id',
           ),
           'langcode' => array(
             'type' => 'varchar',
             'length' => 32,
+            'is_ascii' => true,
             'not null' => true,
             'default' => '',
             'description' => 'The language code for this data item.',
