Di chuyển Laravel: khóa duy nhất quá dài, ngay cả khi được chỉ định


166

Tôi đang cố gắng di chuyển một bảng người dùng trong Laravel. Khi tôi chạy di chuyển, tôi gặp lỗi này:

[Illuminate \ Database \ QueryException] SQLSTATE [42000]: Lỗi cú pháp hoặc vi phạm truy cập: 1071 Khóa được chỉ định quá dài; độ dài khóa tối đa là 767 byte (SQL: bảng thay đổi usersthêm users_email_uniq ( email))

di chuyển của tôi là như sau:

Schema::create('users', function(Blueprint $table)
{
    $table->increments('id');
    $table->string('name', 32);
    $table->string('username', 32);
    $table->string('email', 320);
    $table->string('password', 64);
    $table->string('role', 32);
    $table->string('confirmation_code');
    $table->boolean('confirmed')->default(true);
    $table->timestamps();

    $table->unique('email', 'users_email_uniq');
});

Sau một vài lần googling tôi đã xem qua báo cáo lỗi này , trong đó Taylor nói rằng bạn có thể chỉ định khóa chỉ mục là tham số thứ 2 unique(), mà tôi đã thực hiện. Nó vẫn đưa ra lỗi. Chuyện gì đang xảy ra ở đây?


Tại sao bạn sử dụng 320 ký tự cho e-mail? Đây có thể là vấn đề của bạn.
Antonio Carlos Ribeiro

1
Đó thực sự là vấn đề, không biết tại sao. Nhưng vâng, bạn nói đúng, tôi không biết tại sao tôi lại chỉ định độ dài char cho từng trường. Đã xóa các giới hạn này
harryg

Thật buồn cười khi không ai đề xuất sử dụng trường có độ dài cố định có chứa hàm băm của email và voila - vấn đề được giải quyết mãi mãi, cho bất kỳ khuôn khổ nào và cho bất kỳ cơ sở dữ liệu quan hệ nào. Bởi vì đó là cách chúng tôi đảm bảo tính duy nhất - sử dụng biểu diễn số cố định của đầu vào có độ dài thay đổi, với thực tế là phạm vi số đó đủ lớn (và đối với sha1 / sha256).
NB


Câu trả lời:


280

Chỉ định độ dài nhỏ hơn cho e-mail của bạn:

$table->string('email', 250);

Đó là mặc định, thực sự:

$table->string('email');

Và bạn nên tốt.

Đối với Laravel 5.4, bạn có thể tìm thấy giải pháp trong Laravel 5.4 này: Khóa được chỉ định là lỗi quá dài, bài viết của Laravel News :

Như được nêu trong hướng dẫn Di chuyển để khắc phục điều này, tất cả những gì bạn phải làm là chỉnh sửa tệp AppServiceProvider.php và bên trong phương thức khởi động đặt độ dài chuỗi mặc định:

use Illuminate\Database\Schema\Builder;


public function boot()
{
    Builder::defaultStringLength(191);
}

6
Độ dài email tối đa có thể 254rất đáng để ghi nhớ điều này, vì vậy tôi có thể sẽ xác nhận tính duy nhất bằng cách sử dụng trình xác nhận trong trường hợp đó.
Sebastian Sulinski

12
Đối với Laravel 5.4 , hãy sử dụng \Illuminate\Database\Schema\Builder::defaultStringLength(191);cho đường dẫn tham chiếu chức năng chính xác
webcoder

5
Sau khi thực hiện cấu hình trong AppServiceProvider.php, sự cố này vẫn xảy ra. Tôi chỉ bối rối. Tại sao? Tôi khởi động lại máy chủ, cơ sở dữ liệu và mọi thứ nhưng vẫn còn. Xin vui lòng giúp đỡ.
Koushik Das

3
Bạn phải đặt độ dài của cột được lập chỉ mục theo giới hạn 767 byte. Xin lưu ý rằng VARCHAR có thể có 1, 2 hoặc 4 byte cho mỗi đơn vị độ dài. Ví dụ: utf8_mb4 (4 byte) -> 767/4 = 191. Mặt khác utf8_general_ci cho VARCHAR (X) với X <85 (1 byte) = O (85) hoặc utf8_general_ci cho VARCHAR (X) với X> = 86 byte) -> 767/2 = 383. Cũng xem xét các cột khác chiều dài trong nhiều chỉ mục cột.
Jackie Degl'Innocenti

2
Bạn cũng có thể muốn chỉnh sửa trực tiếp độ dài của cột cụ thể trong các tệp di chuyển, qua việc chỉ định độ dài mặc định cho tất cả các cột chuỗi, vì không phải tất cả các cột sẽ cần ràng buộc này vì chúng không có trong bất kỳ chỉ mục nào. $ bảng-> chuỗi ('cột_name', 191);
Jackie Degl'Innocenti

109

Cập nhật 1

Kể từ Laravel 5.4, những thay đổi đó là không cần thiết nữa.

Laravel 5.4 sử dụng ký tự utf8mb4 được đặt theo mặc định, bao gồm hỗ trợ lưu trữ "biểu tượng cảm xúc" trong cơ sở dữ liệu. Nếu bạn đang nâng cấp ứng dụng của mình từ Laravel 5.3, bạn không bắt buộc phải chuyển sang bộ ký tự này.

Cập nhật 2

Các phiên bản MariaDB sản xuất hiện tại KHÔNG hỗ trợ cài đặt này theo mặc định trên toàn cầu. Nó được triển khai trong MariaDB 10.2.2+ theo mặc định .

Giải pháp

Và nếu bạn cố tình muốn sử dụng đúng utf8mb4hỗ trợ đa byte UTF8 trong tương lai (bắt đầu từ Laravel 5.4) cho thì hãy bắt đầu sửa configuration cấu hình cơ sở dữ liệu của bạn.

Trong Laravel config/database.phpxác định:

'charset' => 'utf8mb4',
'collation' => 'utf8mb4_unicode_ci',
'engine' => 'InnoDB ROW_FORMAT=DYNAMIC',

DYNAMICcho phép lưu trữ các chỉ mục quan trọng dài .

Cài đặt máy chủ (theo mặc định được bao gồm trong MySQL 5.7.7+ / MariaDB 10.2.2+):

[mysqld]
# default character set and collation
collation-server = utf8mb4_unicode_ci
character-set-server = utf8mb4

# utf8mb4 long key index
innodb_large_prefix = 1
innodb_file_format = barracuda
innodb_file_format_max = barracuda
innodb_file_per_table = 1

Đối với khách hàng:

[mysql]
default-character-set=utf8mb4

Và sau đó DỪNG máy chủ MySQL / MariaDB của bạn. Sau đó BẮT ĐẦU. RESTART nóng có thể không hoạt động.

sudo systemctl stop mysqld
sudo systemctl start mysqld

Bây giờ bạn đã có Laravel 5.x với sự hỗ trợ UTF8.


3
Điều này có thể đủ tốt với MySQL 5.5 (không cố gắng cấu hình lại). 5.7 (có lẽ cũng 5.6) hoạt động mà không cần cấu hình lại. 5.7 là bản phân phối Máy chủ Cộng đồng mặc định với cấu hình vanilla.
Pjotr

Tôi đã thay đổi công cụ trong cơ sở dữ liệu của mình như bạn đã đề cập nhưng nó vẫn đang tạo các bảng có row = compact đang gây ra sự cố. Tôi không hiểu đầy đủ, bạn có nói rằng nó không đủ để thực hiện thay đổi này trong cơ sở dữ liệu.php và nó cũng được yêu cầu để thực hiện các thay đổi trong tệp my.cnf?
vesperknight

Nó là đủ để thực hiện các thay đổi chỉ trong database.phptập tin cấu hình và nó sẽ ảnh hưởng đến dự án Laravel cục bộ. Hãy chắc chắn deletecơ sở dữ liệu trước khi thực hiện thay đổi và tạo nó với các cài đặt mới. Bạn chỉ cần thay đổi my.cnftệp cấu hình cho các thay đổi phía máy chủ toàn cầu (hiện tại tất cả các cài đặt mới sử dụng utf8mb4).
Vua phá lưới

Hoặc - thêm một trường khác, tính toán hàm băm của email, làm cho trường duy nhất, giải quyết vấn đề mãi mãi, tránh thay đổi với các biến khởi tạo cơ sở dữ liệu.
NB

Nếu bất cứ ai đang sử dụng Doctrine 2 , bạn có thể đặt ROW_FORMAT bằng cách chuyển options={"row_format"="DYNAMIC"}đến @Tablechú thích của mình .
Albert221

50

Nếu bạn đang bật hoặc cập nhật lên Laravel 5.4 Điều này hiệu quả với tôi;

Chỉ cần 1 thay đổi. trong AppServiceProvider.php

use Illuminate\Support\Facades\Schema;

public function boot()
{
  Schema::defaultStringLength(191);
}

Như đã đề cập trong hướng dẫn di chuyển https://laravel.com/docs/master/migations#creating-indexes


Tôi đã làm điều này trên di chuyển chính nó.
Amirmasoud 17/03/2017

7
Điều này là (có lẽ) bởi vì mỗi ký tự chiếm chính xác 4 byte và độ dài khóa tối đa được đo bằng byte, không phải ký tự. Vì vậy, độ dài khóa sẽ bằng 191 * 4 = 764 byte, chỉ là một smidgen dưới 767 byte tối đa mà cơ sở dữ liệu sẽ hỗ trợ. Các giải pháp cần giải thích IMO nếu họ muốn đóng góp vào kiến ​​thức được chia sẻ ở đây, và không chỉ cung cấp "thủ tục". Nhưng một sửa chữa tiện dụng dù sao.
Jason

33

Nếu bất cứ ai khác vấp phải câu trả lời này như tôi đã làm nhưng vì một lý do khác, bạn có thể kiểm tra bộ ký tự / đối chiếu Laravel DB của mình.

Tôi đã cài đặt một ứng dụng (Snipe-IT) và đã cấu hình cấu hình cơ sở dữ liệu Laravel để sử dụng như sau:

'charset' => 'utf8mb4',
'collation' => 'utf8mb4_general_ci',

Việc xóa mb4khỏi cả hai chuỗi đã khắc phục vấn đề, mặc dù tôi tin rằng câu trả lời của Antonio là giải pháp thực sự cho vấn đề.



16

Xóa mb4 khỏi bộ ký tự và đối chiếu khỏi config / database.php, sau đó nó sẽ thực thi thành công.
'bộ ký tự' => 'utf8',
'đối chiếu' => 'utf8_unicode_ci',


15

Đối với laravel 5.6
Giải pháp này giải quyết vấn đề của tôi,
hãy đi tới config/database.php
Tìm mã bên dưới

'mysql' => [
    'driver' => 'mysql',
    'host' => env('DB_HOST', '127.0.0.1'),
    'port' => env('DB_PORT', '3306'),
    'database' => env('DB_DATABASE', 'forge'),
    'username' => env('DB_USERNAME', 'forge'),
    'password' => env('DB_PASSWORD', ''),
    'unix_socket' => env('DB_SOCKET', ''),
    'charset' => 'utf8mb4',
    'collation' => 'utf8mb4_unicode_ci',
    'prefix' => '',
    'strict' => true,
    'engine' => null,
],

Thay đổi hai lĩnh vực này

'charset' => 'utf8mb4',
'collation' => 'utf8mb4_unicode_ci'

Với cái này

'charset' => 'utf8',
'collation' => 'utf8_unicode_ci'

14

Tôi đã đối mặt với cùng một vấn đề và đã khắc phục nó bằng cách thêm hai dòng dưới đây vào app / database.php của tôi

'charset' => 'utf8',
'collation' => 'utf8_unicode_ci',

Tập tin của tôi trông như dưới đây:

<?php

return [

    /*
    |--------------------------------------------------------------------------
    | Default Database Connection Name
    |--------------------------------------------------------------------------
    |
    | Here you may specify which of the database connections below you wish
    | to use as your default connection for all database work. Of course
    | you may use many connections at once using the Database library.
    |
    */

    'default' => env('DB_CONNECTION', 'mysql'),

    'charset' => 'utf8',
    'collation' => 'utf8_unicode_ci',

    ......

2
Nếu bạn đã cài đặt phiên bản mới trong Laravel. Vui lòng xóa 'mb4' khỏi utf8mb4 & utf8mb4_unicode_ci & config / database.php
Muthu17

13

Đối với laravel 5.4, chỉ cần chỉnh sửa tệp

Ứng dụng \ Nhà cung cấp \ AppServiceProvider.php

use Illuminate\Support\Facades\Schema;

public function boot()
{
    Schema::defaultStringLength(191);
}

7
File: config/database.php
change the following
FROM ->
'charset' => 'utf8mb4',
'collation' => 'utf8mb4_unicode_ci',

TO ->
'charset' => 'utf8',
'collation' => 'utf8_unicode_ci',

1
Trong khi điều này có thể trả lời câu hỏi, tốt hơn là thêm một số mô tả về cách câu trả lời này có thể giúp giải quyết vấn đề. Xin vui lòng đọc Làm thế nào để tôi viết một câu trả lời tốt để biết thêm.
Roshana Pitigala

6

tôi đã có cùng một vấn đề và tôi đang sử dụng một wamp

Giải pháp: Mở tệp: config / database.php

'engine' => null, => 'engine' => 'InnoDB',

Cảm ơn


Không có câu trả lời nào trước đây có tác dụng với tôi, nhưng câu trả lời này có tác dụng như một cơ duyên! Và nó hoàn toàn hợp lý, tôi tin rằng các phiên bản trước của công cụ Laravel DB đã được đặt thành InnoDB theo mặc định để chúng tôi không gặp phải các lỗi này trước đây.
Sasa Blagojevic

có cần thiết để làm một vài câu trả lời khác và điều này là tốt.
Andrew

6

Trong tập tin config / database.php trong đó:

'charset' => 'utf8mb4',
'collation' => 'utf8mb4_unicode_ci',

Thay đổi dòng này thành:

'charset' => 'utf8',
'collation' => 'utf8_unicode_ci',

5

Đối với Laravel> = 5,6 người dùng

Mở AppServiceProvider.phptập tin

Sử dụng lớp sau

use Illuminate\Support\Facades\Schema;

Sau đó, bên trong bootphương thức thêm dòng sau

public function boot()
{
    Schema::defaultStringLength(191);
}

4

Tôi đã thêm vào bản di chuyển

Schema::defaultStringLength(191);
Schema::create('users', function (Blueprint $table) {
    $table->increments('id');
    $table->string('name');
    $table->string('email')->unique();
    $table->string('password');
    $table->rememberToken();
    $table->timestamps();
});

vâng, tôi biết tôi cần xem xét nó trên mỗi lần di chuyển nhưng tôi thà rằng điều đó còn hơn ở một số nhà cung cấp dịch vụ hoàn toàn không liên quan


4

Nếu ai đó có vấn đề này ngay cả sau khi làm, đã đề cập ở trên. Ví dụ, trong trường hợp của tôi, tôi đã thực hiện các thay đổi dưới đây,

namespace App\Providers;
use Illuminate\Support\ServiceProvider;
use Illuminate\Support\Facades\Schema;

class AppServiceProvider extends ServiceProvider
{
  /**
   * Register any application services.
   *
   * @return void
   */
   public function register()
   {
      //
   }

   public function boot()
   {
     Schema::defaultStringLength(191);
   }
}

Nhưng nó sẽ không hoạt động ngay lập tức vì hai lý do. Một là nếu bạn đang sử dụng lum thay vì laravel, trước tiên bạn có thể phải bỏ dòng này trong tệp app.php của mình.

$app->register(App\Providers\AppServiceProvider::class);

Và sau đó bạn phải tạo lại tập lệnh di chuyển với lệnh artisan,

php artisan make:migration <your_table_name>

Vì bây giờ chỉ những thay đổi bạn đã thực hiện cho ServiceProvider mới hoạt động.


4

cho laravel 5.7 viết các mã này trong appserviceprovider.php

  use Illuminate\Support\Facades\Schema;

public function boot()
{
  Schema::defaultStringLength(191);
}

2

Thay đổi bộ ký tự thành từ 'utf8mb4' thành 'utf8' và

đối chiếu với 'utf8mb4_unicode_ci' thành 'utf8_unicode_ci'

trong tập tin config / database.php

Nó làm việc cho tôi.


2

Laravel sử dụng bộ utf8mb4ký tự theo mặc định, bao gồm hỗ trợ lưu trữ "biểu tượng cảm xúc" trong cơ sở dữ liệu. Nếu bạn đang chạy phiên bản MySQL cũ hơn bản phát hành 5.7.7 hoặc MariaDB cũ hơn bản phát hành 10.2.2, bạn có thể cần phải định cấu hình thủ công độ dài chuỗi mặc định được tạo bởi di chuyển để MySQL tạo chỉ mục cho chúng. Bạn có thể định cấu hình điều này bằng cách gọi Schema::defaultStringLengthphương thức trong AppServiceProvider:

use Illuminate\Support\Facades\Schema;

/**
 * Bootstrap any application services.
 *
 * @return void
 */
public function boot()
{
    Schema::defaultStringLength(191);
}

Bạn có thể kiểm tra

https://laravel-news.com/laravel-5-4-key-too-long-error https://laravel.com/docs/5.5/migations#indexes


cảm ơn, làm việc cho tôi mamp mysql với laravel 5.6,23
bluesky

2

Đó là bởi vì Laravel 5.4 sử dụng utf8mb4 hỗ trợ lưu trữ biểu tượng cảm xúc.

Thêm phần này vào ứng dụng của bạn \ Providers \ AppServiceProvider.php

use Illuminate\Support\Facades\Schema;

public function boot()
{
    Schema::defaultStringLength(191);
}

và bạn nên đi thật tốt


2

Nếu bạn đang bật hoặc cập nhật lên Laravel 5.4 và phiên bản mới nhất thì nó hoạt động;
Chỉ cần 1 thay đổi trong AppServiceProvider.php

use Illuminate\Support\Facades\Schema;

public function boot()
{
  Schema::defaultStringLength(191);
}

1

Tôi muốn chỉ ra rằng một cái gì đó mà tôi đã bỏ lỡ ...

Tôi mới sử dụng tại Laravel và tôi đã không sao chép "sử dụng Illuminate ....." vì tôi thực sự không chú ý, vì ngay phía trên chức năng khởi động mà bạn đã đọc có sử dụng Tuyên bố.

Mong rằng sẽ giúp được ai

**use Illuminate\Support\Facades\Schema;**

public function boot()
{
    Schema::defaultStringLength(191);
}

Bạn cũng có thể chỉ cần thêm tiền tố vào bất kỳ Mặt tiền nào với\
Ohgodwhy

1

Tôi gặp sự cố, thay đổi cấu hình của 'config / cơ sở dữ liệu'

file 'charset' => 'utf8',
'collation' => 'utf8_unicode_ci',

giữ mô hình tương tự trong cơ sở dữ liệu.

Sau đó tôi đã ra lệnh

php artisan migrate

1

Vào ngày 24 tháng 10 năm 2016 Taylor Otwell , Tác giả của Laravel đã công bố trên Twitter

"utf8mb4" sẽ là bộ ký tự MySQL mặc định trong Laravel 5.4 để hỗ trợ biểu tượng cảm xúc tốt hơn. 🙌 Bài đăng trên Twitter của Taylor Otwell

mà trước phiên bản 5.4, bộ ký tự là utf8

Trong thế kỷ này, nhiều ứng dụng web, bao gồm trò chuyện hoặc một số nền tảng để cho phép người dùng của họ trò chuyện và nhiều người thích sử dụng biểu tượng cảm xúc hoặc mặt cười. và đây là một số loại siêu ký tự cần nhiều không gian hơn để lưu trữ và điều đó chỉ có thể sử dụng utf8mb4như bộ ký tự . Đó là lý do tại sao họ di chuyển đến utf8mb4chỉ cho mục đích không gian.

nếu bạn tra cứu trong Illuminate\Database\Schema\Builderlớp, bạn sẽ thấy rằng nó $defaultStringLengthđược đặt thành 255 và để sửa đổi rằng bạn có thể xử lý thông qua SchemaMặt tiền và gọi defaultStringLengthphương thức và vượt qua độ dài mới.

để thực hiện thay đổi đó, hãy gọi phương thức đó trong AppServiceProviderlớp của bạn trong thư mục con của ứng dụng \ nhà cung cấp như thế này

class AppServiceProvider extends ServiceProvider
{
    /**
     * Bootstrap any application services.
     *
     * @return void
     */
    public function boot()
    {
        // all other code ...

        Schema::defaultStringLength(191); 
    }
    // and all other code goes here
}

Tôi sẽ đề nghị sử dụng 191 làm giá trị chỉ vì MySQL hỗ trợ 767 byte và bởi vì 767 / 4đó là số byte được lấy bởi mỗi ký tự đa nhân mà bạn sẽ nhận được 191.

Bạn có thể tìm hiểu thêm tại đây Bộ ký tự utf8mb4 (Mã hóa Unicode 4-byte UTF-8) Giới hạn về số lượng cột và kích thước hàng của bảng


Đây là câu trả lời duy nhất giải thích con 191số kỳ diệu.
Illya Moskvin


1

Đi của bạn config/database.phpvà thay đổi charset và collation từ utf8mb4 để utf8

'charset' => 'utf8',
'collation' => 'utf8_unicode_ci',

Vấn đề của tôi được giải quyết bằng phương pháp này, chúc may mắn nhé anh bạn!


0

Bạn sẽ không gặp vấn đề này nếu bạn đang sử dụng MySQL 5.7.7+ hoặc MariaDB 10.2.2+.

Để cập nhật MariaDB trên máy Mac của bạn bằng cách sử dụng Brew trước tiên hãy hủy liên kết hiện tại: brew unlink mariadbvà sau đó cài đặt một nhà phát triển bằng cách sử dụngbrew install mariadb --devel

Sau khi cài đặt xong, dừng / bắt đầu dịch vụ chạy: brew services stop mariadb brew services start mariadb

Phiên bản dev hiện tại là 10.2.3. Sau khi cài đặt xong, bạn sẽ không phải lo lắng về vấn đề này nữa và bạn có thể sử dụng utf8mb4 (hiện là mặc định trong Laravel 5.4) mà không cần quay lại utf8 cũng như chỉnh sửa AppServiceProvider như được đề xuất trong tài liệu của Laravel: https: // laravel .com / docs / master / phát hành # laravel-5.4 (cuộn xuống: Chiều dài chuỗi mặc định di chuyển )


0

Chỉ cần cài đặt MariaDB 10.2.4 RC, khởi động dự án Laravel 5.4 trống mới và các cột di chuyển mặc định (varchar (255)) hoạt động.

Không cần thay đổi DB conf và Laravael config/database.php. Do đó, như @scorer đã lưu ý về hành vi mặc định cho 10.2.2+.


0

Tất cả đã được mô tả tốt trong các Anwser khác, bạn có thể xem thêm chi tiết trong liên kết dưới đây (tìm kiếm với khóa 'Chỉ số độ dài & MySQL / MariaDB ") https://laravel.com/docs/5.5/migations

NHƯNG RELLNG không phải câu trả lời này là gì! Vấn đề là ngay cả khi thực hiện các thao tác trên, bạn sẽ gặp phải một lỗi khác (đó là khi bạn thích php artisan migratelệnh khởi chạy và do vấn đề về độ dài, thao tác như bị kẹt ở giữa. Giải pháp nằm dưới và bảng người dùng giống như được tạo mà không có phần còn lại hoặc không hoàn toàn chính xác) chúng ta cần cuộn bac k. cuộn lại mặc định sẽ không làm. bởi vì hoạt động di chuyển không giống như kết thúc. bạn cần xóa các bảng được tạo mới trong cơ sở dữ liệu theo cách thủ công.

chúng ta có thể làm điều đó bằng cách sử dụng tinker như dưới đây:

L:\todos> php artisan tinker

Psy Shell v0.8.15 (PHP 7.1.10  cli) by Justin Hileman

>>> Schema::drop('users')

=> null

Bản thân tôi đã có một vấn đề với bảng người dùng.

sau đó là tốt để đi

php artisan migrate:rollback

php artisan migrate

0

Đặt công cụ cơ sở dữ liệu InnoDB:

  Schema::create('users', function (Blueprint $table) {
            $table->engine = 'InnoDB';
            $table->increments('id');
            $table->string('name');
            $table->string('email')->unique();
            $table->string('password');
            $table->rememberToken();
            $table->timestamps();
        });

0

Nếu bạn đã thử mọi câu trả lời khác và chúng không hoạt động, bạn có thể loại bỏ tất cả các bảng khỏi cơ sở dữ liệu và sau đó thực hiện lệnh di chuyển tất cả cùng một lúc bằng lệnh này:

php artisan migrate:fresh
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.