Answers.Body: <p>If you have a modern (e.g. Debian 10+) server installed fresh, you should be OK. If not, I believe these are the settings you want in your server config (e.g. <code>/etc/mysql/mariadb.conf.d/50-server.cnf</code> if you're using MariaDB on Debian)</p>
  <pre><code>innodb_large_prefix = 1
  #https://mariadb.com/kb/en/library/innodb-system-variables/#innodb_file_format
  innodb_file_format = barracuda
  # https://mariadb.com/kb/en/library/innodb-system-variables/#innodb_file_per_table
  innodb_file_per_table = 1
  # Set default row format to a Barracuda one. COMPRESSED is useful on a
  # per-table basis.
  innodb_default_row_format = DYNAMIC
  </code></pre>
  <p>The <a href="https://mariadb.com/kb/en/library/innodb-system-variables/#innodb_large_prefix" rel="nofollow noreferrer">large prefix</a> is key here:</p>
  <blockquote>
  <p>If set to 1, tables that use specific row formats are permitted to have index key prefixes up to 3072 bytes. If not set, the limit is 767 bytes.</p>
  </blockquote>
  <p>The row formats allowed are DYNAMIC and COMPRESSED. (The latter can be very handy if you don't do many writes to a table with a lot of compressible data, e.g. activities, but that's probably a special case.)</p>
  <p><strong>So then you don't have to shorten your text fields.</strong></p>
  
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2020-09-18T15:03:11.310Z
Answers.LastActivityDate: 2020-09-18T15:03:11.310Z
Answers.UserDisplayName: artfulrobot
Answers.Body: <p>It's a good question. I haven't come across any problems like this. I see one varchar(512) custom field in utf8mb4 and the longest value it has at the moment is 383 and both the field and index seem fine, but it wasn't converted it's always been utf8mb4. I do have innodb_default_row_format=dynamic which I remember seeing somewhere that's what tables need.</p>
  <p>That article is from 2012 too so some things may have changed.</p>
  <p>For indexes, civi only creates an index for custom fields if you check the is_searchable box, so that could be another way to work around indexes at least if you end up with those troubles.</p>
  <p>Also it's not well-advertised but you can test conversion by using api3 system.utf8conversion which will convert your tables. You don't need to manually run alter table statements.</p>
  
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2020-09-17T23:09:32.177Z
Answers.Text: Super great to know I don't have to manually run the alter statements! I'll do some testing on a local install with the api3 conversion.
Answers.UserDisplayName: RayWright
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2020-09-16T19:02:32.150Z
Answers.LastActivityDate: 2020-09-16T19:02:32.150Z
Answers.UserDisplayName: Demerit
Body: <p>I'm looking into moving our database to utf8mb4 - as indicated will be required in the future. I've been trying to find information about the possible impact in doing so and I found this post: <a href="https://mathiasbynens.be/notes/mysql-utf8mb4" rel="nofollow noreferrer">https://mathiasbynens.be/notes/mysql-utf8mb4</a></p>
  <p>That article indicates the following (it has a nice, thorough explanation if anyone else is interested, this is just the summary of one section):</p>
  <blockquote>
  <p>The InnoDB storage engine has a maximum index length of 767 bytes, so for utf8 or utf8mb4 columns, you can index a maximum of 255 or 191 characters, respectively. If you currently have utf8 columns with indexes longer than 191 characters, you will need to index a smaller number of characters when using utf8mb4. (Because of this, I had to change some indexed VARCHAR(255) columns to VARCHAR(191).)</p>
  </blockquote>
  <p>So does it make sense that if I need to create any custom text fields in the near future (before making the swap) I should go ahead and limit the database field length to 191 (or less)? I'm looking for someone to verify I have not jumped to the wrong conclusion.</p>
  <p>Does this also imply that I should look through my existing data for any fields with data that might be longer than 191 characters - and then adjust? I assume I could not adjust the data but it may be truncated upon conversion to utf8mb4 if it is longer than 191 characters.</p>
  
Tags: <custom-fields><database>
Title: Preparing for move to utfbmb4 should I limit character length?
ThreadText: # Preparing for move to utfbmb4 should I limit character length?
  
  (Asked by: username_0 on 2020-09-16)
  
  I'm looking into moving our database to utf8mb4 - as indicated will be required in the future. I've been trying to find information about the possible impact in doing so and I found this post: <https://mathiasbynens.be/notes/mysql-utf8mb4>
  
  That article indicates the following (it has a nice, thorough explanation if anyone else is interested, this is just the summary of one section):
  
  > The InnoDB storage engine has a maximum index length of 767 bytes, so for utf8 or utf8mb4 columns, you can index a maximum of 255 or 191 characters, respectively. If you currently have utf8 columns with indexes longer than 191 characters, you will need to index a smaller number of characters when using utf8mb4. (Because of this, I had to change some indexed VARCHAR(255) columns to VARCHAR(191).)
  
  So does it make sense that if I need to create any custom text fields in the near future (before making the swap) I should go ahead and limit the database field length to 191 (or less)? I'm looking for someone to verify I have not jumped to the wrong conclusion.
  
  Does this also imply that I should look through my existing data for any fields with data that might be longer than 191 characters - and then adjust? I assume I could not adjust the data but it may be truncated upon conversion to utf8mb4 if it is longer than 191 characters.
  
  **Tags:** custom-fields, database
  
  
  ---
  
  ## 2 answers
  
  ### Answer by username_1 on 2020-09-18. Score: 3
  
  If you have a modern (e.g. Debian 10+) server installed fresh, you should be OK. If not, I believe these are the settings you want in your server config (e.g. `/etc/mysql/mariadb.conf.d/50-server.cnf` if you're using MariaDB on Debian)
  
  ```
  innodb_large_prefix = 1
  #https://mariadb.com/kb/en/library/innodb-system-variables/#innodb_file_format
  innodb_file_format = barracuda
  # https://mariadb.com/kb/en/library/innodb-system-variables/#innodb_file_per_table
  innodb_file_per_table = 1
  # Set default row format to a Barracuda one. COMPRESSED is useful on a
  # per-table basis.
  innodb_default_row_format = DYNAMIC
  
  ```
  
  The [large prefix](https://mariadb.com/kb/en/library/innodb-system-variables/#innodb_large_prefix) is key here:
  
  > If set to 1, tables that use specific row formats are permitted to have index key prefixes up to 3072 bytes. If not set, the limit is 767 bytes.
  
  The row formats allowed are DYNAMIC and COMPRESSED. (The latter can be very handy if you don't do many writes to a table with a lot of compressible data, e.g. activities, but that's probably a special case.)
  
  **So then you don't have to shorten your text fields.**
  
  
  ---
  
  ### Answer by username_2 on 2020-09-16. Score: 2
  
  It's a good question. I haven't come across any problems like this. I see one varchar(512) custom field in utf8mb4 and the longest value it has at the moment is 383 and both the field and index seem fine, but it wasn't converted it's always been utf8mb4. I do have innodb\_default\_row\_format=dynamic which I remember seeing somewhere that's what tables need.
  
  That article is from 2012 too so some things may have changed.
  
  For indexes, civi only creates an index for custom fields if you check the is\_searchable box, so that could be another way to work around indexes at least if you end up with those troubles.
  
  Also it's not well-advertised but you can test conversion by using api3 system.utf8conversion which will convert your tables. You don't need to manually run alter table statements.
  
  > **Comments:**
  > **username_0**: Super great to know I don't have to manually run the alter statements! I'll do some testing on a local install with the api3 conversion.  
  
  ---
  
  